{"_id":"@achasoft/dsh-tasks-manager","_rev":"4-6d9756cd3983fa0638a740c89d362252","name":"@achasoft/dsh-tasks-manager","dist-tags":{"latest":"0.3.0"},"versions":{"0.2.0":{"name":"@achasoft/dsh-tasks-manager","version":"0.2.0","keywords":["deepseek-harness","dsh","dsh-plugin","tasks","kanban","todo","project-management","sqlite","background-jobs","cordis"],"license":"MIT","_id":"@achasoft/dsh-tasks-manager@0.2.0","maintainers":[{"name":"navid.kianfar","email":"navid.kianfar@outlook.com"}],"homepage":"https://github.com/navid-kianfar/dsh-tasks-manager#readme","bugs":{"url":"https://github.com/navid-kianfar/dsh-tasks-manager/issues"},"dsh":{"bundle":{"patch":"./cordis.patch.yml"},"client":{"inject":["@deepseek-ai/dsh-api-remotes","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-ui-conversation","@deepseek-ai/dsh-client-ui-layout","@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-client-ui-settings-plugins","@deepseek-ai/dsh-client-ui-sidebar"],"platform":"web"}},"dist":{"shasum":"a1fd512c2388f5b53d3a51065b2d8ad88ffbea42","tarball":"https://registry.npmjs.org/@achasoft/dsh-tasks-manager/-/dsh-tasks-manager-0.2.0.tgz","fileCount":47,"integrity":"sha512-NququXEzQH4qy0k+6CdKSC+p25iX6wAo/T+IIbmmg9g4eUGAAxA6sKYyOMYKAjXKHUtbqPW1Wv53bAEBafGREg==","signatures":[{"sig":"MEUCIBmmRuGNHX58cZL+IDbxnHLxur0Uxa1ejCpZBra5v4NyAiEAz0cO8cMeJtwUFQFuB/W4RIOpOvAcAqe8DorYQWISvW0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":696648},"main":"lib/index.js","type":"module","types":"./types/index.d.ts","engines":{"node":"^22.19 || >=24"},"exports":{".":{"types":"./types/index.d.ts","default":"./lib/index.js"},"./host":{"types":"./types/host/index.d.ts","default":"./lib/host.js"},"./tools":{"types":"./types/tools/index.d.ts","default":"./lib/tools.js"},"./client":{"default":"./lib/client.js"},"./package.json":"./package.json","./cordis.patch.yml":"./cordis.patch.yml"},"gitHead":"cbf87c609dd33d0481a2a9bed9721d1fd383618f","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json && tsdown","prepare":"tsc -p tsconfig.build.json && tsdown","typecheck":"tsc --noEmit"},"_npmUser":{"name":"navid.kianfar","email":"navid.kianfar@outlook.com"},"repository":{"url":"git+https://github.com/navid-kianfar/dsh-tasks-manager.git","type":"git"},"_npmVersion":"11.19.1","description":"Task management for the DeepSeek Harness: the session todo list, a project task board backed by a queryable SQLite database, and board cards dispatched to the agent as background jobs","directories":{},"_nodeVersion":"25.2.1","dependencies":{"zod":"^4.4.3","clsx":"^2.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"react":"^18.2.0","tsdown":"^0.15.6","vitest":"^3.2.7","happy-dom":"^15.11.7","react-dom":"^18.2.0","typescript":"^5.9.2","@types/node":"^22.20.1","@types/react":"~18.3.1","lightningcss":"^1.30.1","@types/react-dom":"~18.3.1","@deepseek-ai/cordis":"link:../../deepseek-harness/vendor/cordis","@vitest/coverage-v8":"^3.2.7","@deepseek-ai/dsh-jobs":"link:../../deepseek-harness/packages/jobs/jobs","@deepseek-ai/dsh-agent":"link:../../deepseek-harness/packages/core/agent","@deepseek-ai/dsh-brand":"link:../../deepseek-harness/packages/util/brand","@deepseek-ai/dsh-tools":"link:../../deepseek-harness/packages/core/tools","@deepseek-ai/dsh-session":"link:../../deepseek-harness/packages/core/session","@deepseek-ai/schemastery":"link:../../deepseek-harness/vendor/schemastery","@deepseek-ai/dsh-settings":"link:../../deepseek-harness/packages/settings/settings","@deepseek-ai/dsh-subagent":"link:../../deepseek-harness/packages/subagent/subagent","@deepseek-ai/dsh-tool-todo":"link:../../deepseek-harness/packages/todo/tool-todo","@deepseek-ai/dsh-api-remotes":"link:../../deepseek-harness/packages/api/remotes","@deepseek-ai/dsh-client-locale":"link:../../deepseek-harness/packages/client/locale","@deepseek-ai/dsh-host-apiproxy":"link:../../deepseek-harness/packages/host/apiproxy","@deepseek-ai/dsh-client-runtime":"link:../../deepseek-harness/packages/client/runtime","@deepseek-ai/dsh-host-webserver":"link:../../deepseek-harness/packages/host/webserver","@deepseek-ai/dsh-client-ui-slots":"link:../../deepseek-harness/packages/client/ui-slots","@deepseek-ai/dsh-typert-protocol":"link:../../deepseek-harness/packages/typert/protocol","@deepseek-ai/dsh-client-ui-layout":"link:../../deepseek-harness/packages/client/ui-layout","@deepseek-ai/dsh-client-connection":"link:../../deepseek-harness/packages/client/connection","@deepseek-ai/dsh-client-ui-sidebar":"link:../../deepseek-harness/packages/client/ui-sidebar","@deepseek-ai/dsh-client-ui-settings":"link:../../deepseek-harness/packages/client/ui-settings","@deepseek-ai/dsh-session-projection":"link:../../deepseek-harness/packages/session/session-projection","@deepseek-ai/dsh-client-ui-primitives":"link:../../deepseek-harness/packages/client/ui-primitives","@deepseek-ai/dsh-client-ui-conversation":"link:../../deepseek-harness/packages/client/ui-conversation","@deepseek-ai/dsh-client-ui-settings-plugins":"link:../../deepseek-harness/packages/client/ui-settings-plugins"},"peerDependencies":{"@deepseek-ai/cordis":"*","@deepseek-ai/dsh-jobs":"*","@deepseek-ai/dsh-agent":"*","@deepseek-ai/dsh-tools":"*","@deepseek-ai/dsh-session":"*","@deepseek-ai/schemastery":"*","@deepseek-ai/dsh-settings":"*","@deepseek-ai/dsh-tool-todo":"*","@deepseek-ai/dsh-host-apiproxy":"*","@deepseek-ai/dsh-typert-protocol":"*","@deepseek-ai/dsh-client-connection":"*"},"_npmOperationalInternal":{"tmp":"tmp/dsh-tasks-manager_0.2.0_1788118442626_0.7290031698250035","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@achasoft/dsh-tasks-manager","version":"0.2.1","keywords":["deepseek-harness","dsh","dsh-plugin","tasks","kanban","todo","project-management","sqlite","background-jobs","cordis"],"license":"MIT","_id":"@achasoft/dsh-tasks-manager@0.2.1","maintainers":[{"name":"navid.kianfar","email":"navid.kianfar@outlook.com"}],"homepage":"https://github.com/navid-kianfar/dsh-tasks-manager#readme","bugs":{"url":"https://github.com/navid-kianfar/dsh-tasks-manager/issues"},"dsh":{"bundle":{"patch":"./cordis.patch.yml"},"client":{"inject":["@deepseek-ai/dsh-api-remotes","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-ui-conversation","@deepseek-ai/dsh-client-ui-layout","@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-client-ui-settings-plugins","@deepseek-ai/dsh-client-ui-sidebar"],"platform":"web"}},"dist":{"shasum":"2678f73b5c7a075608d5fdcdb1910778700e9dad","tarball":"https://registry.npmjs.org/@achasoft/dsh-tasks-manager/-/dsh-tasks-manager-0.2.1.tgz","fileCount":47,"integrity":"sha512-hdIz0EYcop335E1WoEv8805/f7HMtYz/b9djjNpMIE8CqpkEyzfNTxtBWabdO4MJKMTqQS2KlHH99B3q+eVi2Q==","signatures":[{"sig":"MEYCIQDXFlO61RwTZ0O72yHX6wOZj12aYvK9oj8RxQxI15IPYgIhAMQdQ+dNWk56QU95vEwecRRzE3BZQl7MIFZZZY7PDsbI","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":699606},"main":"lib/index.js","type":"module","types":"./types/index.d.ts","engines":{"node":"^22.19 || >=24"},"exports":{".":{"types":"./types/index.d.ts","default":"./lib/index.js"},"./host":{"types":"./types/host/index.d.ts","default":"./lib/host.js"},"./tools":{"types":"./types/tools/index.d.ts","default":"./lib/tools.js"},"./client":{"default":"./lib/client.js"},"./package.json":"./package.json","./cordis.patch.yml":"./cordis.patch.yml"},"gitHead":"cb98b3add42a94d684ad734e7d98cf3e935eef93","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json && tsdown","prepare":"tsc -p tsconfig.build.json && tsdown","typecheck":"tsc --noEmit"},"_npmUser":{"name":"navid.kianfar","email":"navid.kianfar@outlook.com"},"repository":{"url":"git+https://github.com/navid-kianfar/dsh-tasks-manager.git","type":"git"},"_npmVersion":"11.19.1","description":"Task management for the DeepSeek Harness: the session todo list, a project task board backed by a queryable SQLite database, and board cards dispatched to the agent as background jobs","directories":{},"_nodeVersion":"25.2.1","dependencies":{"zod":"^4.4.3","clsx":"^2.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"react":"^18.2.0","tsdown":"^0.15.6","vitest":"^3.2.7","happy-dom":"^15.11.7","react-dom":"^18.2.0","typescript":"^5.9.2","@types/node":"^22.20.1","@types/react":"~18.3.1","lightningcss":"^1.30.1","@types/react-dom":"~18.3.1","@deepseek-ai/cordis":"link:../../deepseek-harness/vendor/cordis","@vitest/coverage-v8":"^3.2.7","@deepseek-ai/dsh-jobs":"link:../../deepseek-harness/packages/jobs/jobs","@deepseek-ai/dsh-agent":"link:../../deepseek-harness/packages/core/agent","@deepseek-ai/dsh-brand":"link:../../deepseek-harness/packages/util/brand","@deepseek-ai/dsh-tools":"link:../../deepseek-harness/packages/core/tools","@deepseek-ai/dsh-session":"link:../../deepseek-harness/packages/core/session","@deepseek-ai/schemastery":"link:../../deepseek-harness/vendor/schemastery","@deepseek-ai/dsh-settings":"link:../../deepseek-harness/packages/settings/settings","@deepseek-ai/dsh-subagent":"link:../../deepseek-harness/packages/subagent/subagent","@deepseek-ai/dsh-tool-todo":"link:../../deepseek-harness/packages/todo/tool-todo","@deepseek-ai/dsh-api-remotes":"link:../../deepseek-harness/packages/api/remotes","@deepseek-ai/dsh-client-locale":"link:../../deepseek-harness/packages/client/locale","@deepseek-ai/dsh-host-apiproxy":"link:../../deepseek-harness/packages/host/apiproxy","@deepseek-ai/dsh-client-runtime":"link:../../deepseek-harness/packages/client/runtime","@deepseek-ai/dsh-host-webserver":"link:../../deepseek-harness/packages/host/webserver","@deepseek-ai/dsh-client-ui-slots":"link:../../deepseek-harness/packages/client/ui-slots","@deepseek-ai/dsh-typert-protocol":"link:../../deepseek-harness/packages/typert/protocol","@deepseek-ai/dsh-client-ui-layout":"link:../../deepseek-harness/packages/client/ui-layout","@deepseek-ai/dsh-client-connection":"link:../../deepseek-harness/packages/client/connection","@deepseek-ai/dsh-client-ui-sidebar":"link:../../deepseek-harness/packages/client/ui-sidebar","@deepseek-ai/dsh-client-ui-settings":"link:../../deepseek-harness/packages/client/ui-settings","@deepseek-ai/dsh-session-projection":"link:../../deepseek-harness/packages/session/session-projection","@deepseek-ai/dsh-client-ui-primitives":"link:../../deepseek-harness/packages/client/ui-primitives","@deepseek-ai/dsh-client-ui-conversation":"link:../../deepseek-harness/packages/client/ui-conversation","@deepseek-ai/dsh-client-ui-settings-plugins":"link:../../deepseek-harness/packages/client/ui-settings-plugins"},"peerDependencies":{"@deepseek-ai/cordis":"*","@deepseek-ai/dsh-jobs":"*","@deepseek-ai/dsh-agent":"*","@deepseek-ai/dsh-tools":"*","@deepseek-ai/dsh-session":"*","@deepseek-ai/schemastery":"*","@deepseek-ai/dsh-settings":"*","@deepseek-ai/dsh-tool-todo":"*","@deepseek-ai/dsh-host-apiproxy":"*","@deepseek-ai/dsh-typert-protocol":"*","@deepseek-ai/dsh-client-connection":"*"},"_npmOperationalInternal":{"tmp":"tmp/dsh-tasks-manager_0.2.1_1789475826248_0.3611296488714011","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"@achasoft/dsh-tasks-manager","version":"0.2.2","keywords":["deepseek-harness","dsh","dsh-plugin","tasks","kanban","todo","project-management","sqlite","background-jobs","cordis"],"license":"MIT","_id":"@achasoft/dsh-tasks-manager@0.2.2","maintainers":[{"name":"navid.kianfar","email":"navid.kianfar@outlook.com"}],"homepage":"https://github.com/navid-kianfar/dsh-tasks-manager#readme","bugs":{"url":"https://github.com/navid-kianfar/dsh-tasks-manager/issues"},"dsh":{"bundle":{"patch":"./cordis.patch.yml"},"client":{"inject":["@deepseek-ai/dsh-api-remotes","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-ui-conversation","@deepseek-ai/dsh-client-ui-layout","@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-client-ui-settings-plugins","@deepseek-ai/dsh-client-ui-sidebar"],"platform":"web"}},"dist":{"shasum":"b5405690eec26d9149c893b31a4a138ba686ee44","tarball":"https://registry.npmjs.org/@achasoft/dsh-tasks-manager/-/dsh-tasks-manager-0.2.2.tgz","fileCount":48,"integrity":"sha512-fbQSv1SHU5YPSlBEcKA9MeeZt7gzKq3AUPCFbZEYLFUB+qQ+jDUNGemyS/Q9Rq0qC+Sw0P/8JHiA+EfxkIwb6Q==","signatures":[{"sig":"MEUCIQD6NiyfvbNJLAMxgQOZ0rRJ2lyu3WqLMEK7NxzJPyZtigIgBDdXAl3tdV6CM/aiIkB29hvxBztTt5LDYe2av6Oxneg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":708569},"main":"lib/index.js","type":"module","types":"./types/index.d.ts","engines":{"node":"^22.19 || >=24"},"exports":{".":{"types":"./types/index.d.ts","default":"./lib/index.js"},"./host":{"types":"./types/host/index.d.ts","default":"./lib/host.js"},"./tools":{"types":"./types/tools/index.d.ts","default":"./lib/tools.js"},"./client":{"default":"./lib/client.js"},"./package.json":"./package.json","./cordis.patch.yml":"./cordis.patch.yml"},"gitHead":"3a008d65ffd632a693aaf62be5a2d148b0cda586","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json && tsdown","prepare":"tsc -p tsconfig.build.json && tsdown","typecheck":"tsc --noEmit"},"_npmUser":{"name":"navid.kianfar","email":"navid.kianfar@outlook.com"},"repository":{"url":"git+https://github.com/navid-kianfar/dsh-tasks-manager.git","type":"git"},"_npmVersion":"11.19.1","description":"Task management for the DeepSeek Harness: the session todo list, a project task board backed by a queryable SQLite database, and board cards dispatched to the agent as background jobs","directories":{},"_nodeVersion":"25.2.1","dependencies":{"zod":"^4.4.3","clsx":"^2.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"react":"^18.2.0","tsdown":"^0.15.6","vitest":"^3.2.7","happy-dom":"^15.11.7","react-dom":"^18.2.0","typescript":"^5.9.2","@types/node":"^22.20.1","@types/react":"~18.3.1","lightningcss":"^1.30.1","@types/react-dom":"~18.3.1","@deepseek-ai/cordis":"link:../../deepseek-harness/vendor/cordis","@vitest/coverage-v8":"^3.2.7","@deepseek-ai/dsh-jobs":"link:../../deepseek-harness/packages/jobs/jobs","@deepseek-ai/dsh-agent":"link:../../deepseek-harness/packages/core/agent","@deepseek-ai/dsh-brand":"link:../../deepseek-harness/packages/util/brand","@deepseek-ai/dsh-tools":"link:../../deepseek-harness/packages/core/tools","@deepseek-ai/dsh-session":"link:../../deepseek-harness/packages/core/session","@deepseek-ai/schemastery":"link:../../deepseek-harness/vendor/schemastery","@deepseek-ai/dsh-settings":"link:../../deepseek-harness/packages/settings/settings","@deepseek-ai/dsh-subagent":"link:../../deepseek-harness/packages/subagent/subagent","@deepseek-ai/dsh-tool-todo":"link:../../deepseek-harness/packages/todo/tool-todo","@deepseek-ai/dsh-api-remotes":"link:../../deepseek-harness/packages/api/remotes","@deepseek-ai/dsh-client-locale":"link:../../deepseek-harness/packages/client/locale","@deepseek-ai/dsh-host-apiproxy":"link:../../deepseek-harness/packages/host/apiproxy","@deepseek-ai/dsh-client-runtime":"link:../../deepseek-harness/packages/client/runtime","@deepseek-ai/dsh-host-webserver":"link:../../deepseek-harness/packages/host/webserver","@deepseek-ai/dsh-client-ui-slots":"link:../../deepseek-harness/packages/client/ui-slots","@deepseek-ai/dsh-typert-protocol":"link:../../deepseek-harness/packages/typert/protocol","@deepseek-ai/dsh-client-ui-layout":"link:../../deepseek-harness/packages/client/ui-layout","@deepseek-ai/dsh-client-connection":"link:../../deepseek-harness/packages/client/connection","@deepseek-ai/dsh-client-ui-sidebar":"link:../../deepseek-harness/packages/client/ui-sidebar","@deepseek-ai/dsh-client-ui-settings":"link:../../deepseek-harness/packages/client/ui-settings","@deepseek-ai/dsh-session-projection":"link:../../deepseek-harness/packages/session/session-projection","@deepseek-ai/dsh-client-ui-primitives":"link:../../deepseek-harness/packages/client/ui-primitives","@deepseek-ai/dsh-client-ui-conversation":"link:../../deepseek-harness/packages/client/ui-conversation","@deepseek-ai/dsh-client-ui-settings-plugins":"link:../../deepseek-harness/packages/client/ui-settings-plugins"},"peerDependencies":{"@deepseek-ai/cordis":"*","@deepseek-ai/dsh-jobs":"*","@deepseek-ai/dsh-agent":"*","@deepseek-ai/dsh-tools":"*","@deepseek-ai/dsh-session":"*","@deepseek-ai/schemastery":"*","@deepseek-ai/dsh-settings":"*","@deepseek-ai/dsh-tool-todo":"*","@deepseek-ai/dsh-host-apiproxy":"*","@deepseek-ai/dsh-typert-protocol":"*","@deepseek-ai/dsh-client-connection":"*"},"_npmOperationalInternal":{"tmp":"tmp/dsh-tasks-manager_0.2.2_1789477432030_0.6296020360182728","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@achasoft/dsh-tasks-manager","version":"0.3.0","description":"Task management for the DeepSeek Harness: the session todo list, a project task board backed by a queryable SQLite database, and board cards dispatched to the agent as background jobs","license":"MIT","type":"module","main":"lib/index.js","types":"./types/index.d.ts","exports":{".":{"types":"./types/index.d.ts","default":"./lib/index.js"},"./host":{"types":"./types/host/index.d.ts","default":"./lib/host.js"},"./tools":{"types":"./types/tools/index.d.ts","default":"./lib/tools.js"},"./client":{"default":"./lib/client.js"},"./cordis.patch.yml":"./cordis.patch.yml","./package.json":"./package.json"},"dsh":{"bundle":{"patch":"./cordis.patch.yml"},"client":{"platform":"web","inject":["@deepseek-ai/dsh-api-remotes","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-ui-conversation","@deepseek-ai/dsh-client-ui-layout","@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-client-ui-settings-plugins","@deepseek-ai/dsh-client-ui-sidebar"]}},"scripts":{"build":"tsc -p tsconfig.build.json && tsdown","prepare":"tsc -p tsconfig.build.json && tsdown","typecheck":"tsc --noEmit","test":"vitest run"},"peerDependencies":{"@deepseek-ai/cordis":"*","@deepseek-ai/dsh-agent":"*","@deepseek-ai/dsh-client-connection":"*","@deepseek-ai/dsh-host-apiproxy":"*","@deepseek-ai/dsh-jobs":"*","@deepseek-ai/dsh-session":"*","@deepseek-ai/dsh-tool-todo":"*","@deepseek-ai/dsh-tools":"*","@deepseek-ai/dsh-typert-protocol":"*","@deepseek-ai/schemastery":"*"},"dependencies":{"clsx":"^2.1.1","zod":"^4.4.3"},"devDependencies":{"@deepseek-ai/cordis":"link:../../deepseek-harness/vendor/cordis","@deepseek-ai/dsh-agent":"link:../../deepseek-harness/packages/core/agent","@deepseek-ai/dsh-api-remotes":"link:../../deepseek-harness/packages/api/remotes","@deepseek-ai/dsh-brand":"link:../../deepseek-harness/packages/util/brand","@deepseek-ai/dsh-client-connection":"link:../../deepseek-harness/packages/client/connection","@deepseek-ai/dsh-client-locale":"link:../../deepseek-harness/packages/client/locale","@deepseek-ai/dsh-client-runtime":"link:../../deepseek-harness/packages/client/runtime","@deepseek-ai/dsh-client-ui-conversation":"link:../../deepseek-harness/packages/client/ui-conversation","@deepseek-ai/dsh-client-ui-layout":"link:../../deepseek-harness/packages/client/ui-layout","@deepseek-ai/dsh-client-ui-primitives":"link:../../deepseek-harness/packages/client/ui-primitives","@deepseek-ai/dsh-client-ui-settings":"link:../../deepseek-harness/packages/client/ui-settings","@deepseek-ai/dsh-client-ui-settings-plugins":"link:../../deepseek-harness/packages/client/ui-settings-plugins","@deepseek-ai/dsh-client-ui-sidebar":"link:../../deepseek-harness/packages/client/ui-sidebar","@deepseek-ai/dsh-client-ui-slots":"link:../../deepseek-harness/packages/client/ui-slots","@deepseek-ai/dsh-host-apiproxy":"link:../../deepseek-harness/packages/host/apiproxy","@deepseek-ai/dsh-host-webserver":"link:../../deepseek-harness/packages/host/webserver","@deepseek-ai/dsh-jobs":"link:../../deepseek-harness/packages/jobs/jobs","@deepseek-ai/dsh-session":"link:../../deepseek-harness/packages/core/session","@deepseek-ai/dsh-session-projection":"link:../../deepseek-harness/packages/session/session-projection","@deepseek-ai/dsh-settings":"link:../../deepseek-harness/packages/settings/settings","@deepseek-ai/dsh-subagent":"link:../../deepseek-harness/packages/subagent/subagent","@deepseek-ai/dsh-tool-todo":"link:../../deepseek-harness/packages/todo/tool-todo","@deepseek-ai/dsh-tools":"link:../../deepseek-harness/packages/core/tools","@deepseek-ai/dsh-typert-protocol":"link:../../deepseek-harness/packages/typert/protocol","@deepseek-ai/schemastery":"link:../../deepseek-harness/vendor/schemastery","@types/node":"^22.20.1","@types/react":"~18.3.1","@types/react-dom":"~18.3.1","@vitest/coverage-v8":"^3.2.7","happy-dom":"^15.11.7","lightningcss":"^1.30.1","react":"^18.2.0","react-dom":"^18.2.0","tsdown":"^0.15.6","typescript":"^5.9.2","vitest":"^3.2.7"},"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/navid-kianfar/dsh-tasks-manager.git"},"keywords":["deepseek-harness","dsh","dsh-plugin","tasks","kanban","todo","project-management","sqlite","background-jobs","cordis"],"engines":{"node":"^22.19 || >=24"},"gitHead":"edf300690ce9743e891c98df3c1ecb5c6b5607df","_id":"@achasoft/dsh-tasks-manager@0.3.0","bugs":{"url":"https://github.com/navid-kianfar/dsh-tasks-manager/issues"},"homepage":"https://github.com/navid-kianfar/dsh-tasks-manager#readme","_nodeVersion":"25.2.1","_npmVersion":"11.19.1","dist":{"integrity":"sha512-kBkFIwp9ghPK+M18nssckXJWhPtRxZCXFgKemcZB7aKBZX3fGLbk+Z6jF/g03TmuIJyUHxfTkG/jhoqQ0YuDUg==","shasum":"9e878c5046a520e252c45401f4adaa3faa0f6a46","tarball":"https://registry.npmjs.org/@achasoft/dsh-tasks-manager/-/dsh-tasks-manager-0.3.0.tgz","fileCount":52,"unpackedSize":864162,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDB4Cah6phxDWrDHfyGrYZXf7AO8l7w3bAi5ft1qleFdwIgHE7XB5c99wxqUa1wi5+bYpaXFW2+lse8xJyXQH9Y6No="}]},"_npmUser":{"name":"navid.kianfar","email":"navid.kianfar@outlook.com"},"directories":{},"maintainers":[{"name":"navid.kianfar","email":"navid.kianfar@outlook.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dsh-tasks-manager_0.3.0_1789536886302_0.037320939905100214"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-30T19:34:02.407Z","modified":"2026-09-16T05:34:46.611Z","0.2.0":"2026-08-30T19:34:02.775Z","0.2.1":"2026-09-15T12:37:06.385Z","0.2.2":"2026-09-15T13:03:52.158Z","0.3.0":"2026-09-16T05:34:46.452Z"},"bugs":{"url":"https://github.com/navid-kianfar/dsh-tasks-manager/issues"},"license":"MIT","homepage":"https://github.com/navid-kianfar/dsh-tasks-manager#readme","keywords":["deepseek-harness","dsh","dsh-plugin","tasks","kanban","todo","project-management","sqlite","background-jobs","cordis"],"repository":{"type":"git","url":"git+https://github.com/navid-kianfar/dsh-tasks-manager.git"},"description":"Task management for the DeepSeek Harness: the session todo list, a project task board backed by a queryable SQLite database, and board cards dispatched to the agent as background jobs","maintainers":[{"name":"navid.kianfar","email":"navid.kianfar@outlook.com"}],"readme":"# @achasoft/dsh-tasks-manager\n\nA project task board for the [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (`dsh`). Each project gets a SQLite database at `<project>/.dsh/tasks.db`. The Web Client gets a **Tasks** tab with a kanban board, a list view, the session's `todo_write` checklist, and a panel of background jobs. The model gets tools to add, list, update, and comment on cards. When a subagent provider is configured, you can dispatch a card to run as a background job; the result is recorded on the card.\n\n![The Tasks tab showing the kanban board with Backlog, To do, In progress, Blocked and Done columns, priorities, labels, due dates, and the database path in the footer](https://raw.githubusercontent.com/navid-kianfar/dsh-tasks-manager/main/docs/screenshots/tasks-board.png)\n\n## Features\n\n### The Tasks tab\n\nA **Tasks** tab sits beside Chat and Trajectory in every session and shows the board of that session's project. The toolbar switches between four layouts (**Board**, **List**, **Session**, **Background**) and has a search box (titles and descriptions), a **Filters** menu (status, priority, labels, assignee, active/archived/all), **Refresh**, and **New task**. The footer shows the database path.\n\n- **Board**: five columns (`backlog`, `todo`, `in_progress`, `blocked`, `done`) with drag and drop between and within columns, a quick-add per column, and a per-card menu (Open, Dispatch to agent, Stop the background run, Archive or Restore, Delete permanently).\n- **List**: one row per card, sortable by column.\n\n![The List layout showing ref, title, labels, status, priority, assignee, due date, and updated columns](https://raw.githubusercontent.com/navid-kianfar/dsh-tasks-manager/main/docs/screenshots/tasks-list-view.png)\n\nThe open board polls a revision counter every `pollIntervalMs` and re-reads cards only when it changes. Changes made by the agent, another session, another `dsh` process, or `sqlite3` therefore appear without a reload.\n\n### Card detail\n\nOpening a card shows an editable title, a Markdown description, status and priority pickers, a due-date calendar, label chips completed from labels already on the board, comments you can edit and delete, a **History** of every change, and the last run's outcome.\n\nThe **Assignee** picker lists people who have committed to the project, from `git log` (last 5,000 commits), ranked by commit count, with the identity from `git config user.email` marked *you*. A value already on a card that is not in the history stays selectable. In a directory without git history, the picker says so.\n\n![A card detail panel with status, priority, assignee, due date, labels, and a Markdown description with a checklist](https://raw.githubusercontent.com/navid-kianfar/dsh-tasks-manager/main/docs/screenshots/tasks-card-detail.png)\n\nField edits made in the detail, and moves on the board (drag or keyboard), are sent with the card's `updatedAt` as it was when the change began: when you entered the title or opened the description editor, or picked the card up. Your own earlier edits to the card carry that stamp forward. If anyone else changed the card in the meantime, the change is refused, the board shows the message, and the board and card reload.\n\n### Session checklist\n\nThe **Session** layout shows the checklist the assistant keeps with `todo_write` for this session, with progress, and an **Add to board** action that copies an unfinished step onto the board.\n\n### Background jobs and dispatch\n\nThe **Background** layout lists every background job the session can see: shell commands, subagents, and dispatched cards, with status, elapsed time, and a **Stop** control. **Read output** shows a dispatched card's final report. For other job kinds the output is withheld, because the job registry has one consuming read cursor per job, and that cursor belongs to the agent's `job_output`.\n\nWhen `subagentProvider` is set, **Dispatch to agent** starts the card as a background job on that subagent provider. The prompt includes the card's title, status, priority, labels, assignee, description, and comments. While it runs:\n\n- the card shows **Running** with a stop control, and moves to `dispatchStatus`;\n- the owning agent is not woken when the run finishes (the plugin holds the job's completion notice), but `job_list` and `job_output` still show it.\n\nWhen it ends, the card's last run records the status (`completed`, `failed`, or `killed`). The subagent's output, or for a failed run its diagnostic and partial output, is added as a comment and returned by `job_output`. On `completed`, the card moves to `dispatchCompletedStatus` unless that is `none`. The outcome is recorded by database path, so it still reaches the card after a settings save or plugin reload.\n\nDeleting a running card first stops its run, acting as the session that owns the job. If the run belongs to another live `dsh` process, the delete is refused.\n\nA card marked running by an older build of this plugin shows **Running (owner unknown)**: that marker does not say which `dsh` process owns the run, so it is never cleared automatically. Its stop control becomes **Clear the running marker**, and **Dispatch to agent** and **Delete** stay available; each of the three asks you to confirm first, because the old run may still be going in another `dsh` process, and clearing the marker does not stop it there. See [Run ownership](#run-ownership-and-stale-markers).\n\n### Settings card\n\n**Settings → Plugins → Task management** edits the fields marked in [Configuration](#configuration).\n\n![The Task management settings card expanded, showing database location, column and position for new tasks, refresh interval, subagent for dispatch, dispatch column moves, and digest size](https://raw.githubusercontent.com/navid-kianfar/dsh-tasks-manager/main/docs/screenshots/tasks-settings-card.png)\n\n## Requirements\n\n- **Harness:** tested with `@deepseek-ai/dsh` 0.1.5-rc.2.\n- **Node.js:** `^22.19 || >=24` (`engines` in `package.json`). The board uses the built-in `node:sqlite` module (`DatabaseSync`); there is no native dependency to install. Some Node versions print an `ExperimentalWarning` for it.\n- **pnpm** on `PATH`: `dsh plugin` forwards to it.\n- **git** on `PATH` (optional): only needed for the assignee picker.\n- **Harness services:** peer dependencies are `@deepseek-ai/cordis`, `dsh-agent`, `dsh-client-connection`, `dsh-host-apiproxy`, `dsh-jobs`, `dsh-session`, `dsh-tool-todo`, `dsh-tools`, `dsh-typert-protocol`, and `schemastery`. Every host-side service is read optionally, and features degrade when it is absent:\n\n| Service | Provided by (standard `dsh-base` / web profile) | Without it |\n| --- | --- | --- |\n| `sessions` | core harness | The RPC channel resolves only sessions found through persistence. |\n| `agents` | core harness | Dispatch fails. |\n| `sessionPersistence` | `dsh-session-persistence-jsonl` | A tab on a session that is no longer live cannot find its board. |\n| `connection`, `webServer` | web profile | No `/dsh-tasks` RPC channel (headless); tools still work. |\n| `jobs` | `dsh-jobs-local` | Dispatch and the Background layout are unavailable. |\n| `subagents` + a named provider | `dsh-subagent-*` (`spawn`, `fork` in `dsh-base`) | Dispatch is hidden. |\n| `todos` projection | `dsh-tool-todo` | The Session layout says the checklist is unavailable. |\n| `settings` | `dsh-settings-file` | No Settings card or live edits; the patch row is used. |\n\nThe browser half needs `dsh-api-remotes`, `dsh-client-locale`, `dsh-client-ui-conversation`, `dsh-client-ui-layout`, `dsh-client-ui-settings`, `dsh-client-ui-settings-plugins`, and `dsh-client-ui-sidebar`.\n\n## Install\n\n```bash\ndsh plugin --profile web add @achasoft/dsh-tasks-manager\ndsh web\n```\n\n`dsh plugin --profile <name> <args>` runs `pnpm <args>` in `$DSH_HOME/profiles/<name>` (`$DSH_HOME` defaults to `~/.dsh`) and creates the profile on first use. After a successful `add`, any dependency whose `package.json` declares `dsh.bundle` is appended to `dsh.profile.bundles`.\n\nAt boot the harness composes the profile from patch layers, in this order: each bundle's `cordis.patch.yml`, the profile's own `cordis.patch.yml`, `$DSH_HOME/cordis.patch.yml`, then `--patch <file>` overlays. This package's patch inserts three rows, all enabled:\n\n| Row `id` | Loads |\n| --- | --- |\n| `tasks` | `@achasoft/dsh-tasks-manager/host`: the board, the RPC channel, settings, dispatch |\n| `tasks-tools` | `@achasoft/dsh-tasks-manager/tools`: model-facing tools |\n| `tasks-ui` | `@achasoft/dsh-tasks-manager`: the browser half |\n\nTo enable dispatch, set `subagentProvider` in the Settings card or in a patch (see below).\n\nTo keep the board for people but give the model no access, disable the tools row:\n\n```yaml\n- id: tasks-tools\n  disabled: true\n```\n\nTo uninstall:\n\n```bash\ndsh plugin --profile web remove @achasoft/dsh-tasks-manager\n```\n\nRemove any rows in your own patch files that target the ids above. `.dsh/tasks.db` files in your projects are left in place.\n\n## Configuration\n\nOverride a row from your profile's `cordis.patch.yml` by `id`. A patch replaces the row's whole `config`, so restate every key:\n\n```yaml\n- id: tasks\n  config:\n    databasePath: .dsh/tasks.db\n    projectRootMarkers:\n      - .git\n    defaultStatus: backlog\n    newTaskPlacement: top\n    journalMode: wal\n    busyTimeoutMs: 5000\n    pollIntervalMs: 2000\n    subagentProvider: spawn\n    dispatchStatus: in_progress\n    dispatchCompletedStatus: none\n    digestSize: 25\n```\n\nThe patch row is the base layer. Values saved from the Settings card go to the harness settings layer (the `tasks:` section of `$DSH_HOME/settings.yaml`) and take precedence. Saving a change closes and reopens every open board.\n\n### `tasks` row\n\n| Key | Default | In Settings card | What it does |\n| --- | --- | --- | --- |\n| `databasePath` | `.dsh/tasks.db` | yes | Relative paths resolve against the project root. An absolute path makes every project share one board. |\n| `projectRootMarkers` | `['.git']` | no | Entry names looked for from the session directory upwards. The first match is the project root; with no match, the session directory is the root. |\n| `defaultStatus` | `backlog` | yes | Column for a card created without one: `task_add` without `status`, **Add to board** from the checklist, and the toolbar's **New task** composer. When a status filter hides this column, the composer uses the first filtered column so the card stays in view. A column's own quick-add always uses that column. |\n| `newTaskPlacement` | `top` | yes | `top` or `bottom` of the column. |\n| `journalMode` | `wal` | no | `wal`, `delete`, `truncate`, or `persist`. |\n| `busyTimeoutMs` | `5000` | no | How long a write waits for another writer. |\n| `pollIntervalMs` | `2000` | yes | Revision poll interval for an open board; minimum 250. |\n| `subagentProvider` | `''` | yes | Subagent provider name for dispatch. Empty hides dispatch. |\n| `dispatchStatus` | `in_progress` | yes | Column a card moves to on dispatch; `none` leaves it. |\n| `dispatchCompletedStatus` | `none` | yes | Column a card moves to when its run completes; `none` leaves it. |\n| `digestSize` | `25` | yes | Cards `task_list` returns with `sort: urgency` and no `limit`; 1–200. |\n\n### `tasks-tools` row\n\n| Key | Default | What it does |\n| --- | --- | --- |\n| `allowDelete` | `false` | Registers `task_delete`. Archiving is recoverable; deleting is not. |\n| `defaultListLimit` | `50` | Cards `task_list` returns with no `limit`; 1–200. |\n\nNeither key is editable in the Settings card.\n\n## Model-facing tools\n\nTools resolve the board from the calling agent's session directory. Cards can be referred to as `#12`, `12`, or the full `t_…` id. Tool writes are recorded in history as `agent`.\n\n| Tool | What it does |\n| --- | --- |\n| `task_add` | Add one or more cards in one transaction (title, body, status, priority, labels, assignee, due date `YYYY-MM-DD`). |\n| `task_list` | Read the board with filters (`status`, `priority`, `labels`, `assignee`, `search`, `archived`, `limit`). `sort: urgency` returns only unfinished, unarchived cards, most pressing first. |\n| `task_update` | Change title, body, status, priority, labels (replaces the set), assignee, due date, or `archived`. |\n| `task_comment` | Add a Markdown comment. |\n| `task_delete` | Permanently delete a card, its comments, and history, stopping any run first. Refuses a card whose running marker has no recorded owner; a person clears that marker on the board. Registered only with `allowDelete: true`. |\n\nLimits: title 200 characters, body and comment 20,000, up to 20 labels of 40 characters, assignee 80.\n\n## RPC\n\nThe browser half talks to the host over the harness's unary RPC channel at `/dsh-tasks`. The route is mounted on the web server behind the connection's request gate (Host/Origin check and browser token). Every request carries a `sessionId`; the host resolves the board from that session's working directory, and the browser never sends a filesystem path. Validation errors, unknown cards, and stale edits and moves come back as `bad-request`.\n\nEndpoints: `board.read`, `board.revision`, `task.detail`, `task.create`, `task.update` (optional `expectedUpdatedAt`), `task.move` (optional `expectedUpdatedAt`), `task.archive`, `task.restore`, `task.delete` (optional `clearUnknownRun`), `task.clearRun` (`taskId`, `jobId`), `comment.add`, `comment.edit`, `comment.remove`, `task.dispatch` (optional `clearUnknownRun`), `jobs.list`, `jobs.read`, `jobs.kill`, `git.authors`.\n\nA card whose running marker records no owner carries `runOwnerUnknown: true`. `task.dispatch` and `task.delete` refuse such a card with `bad-request` unless `clearUnknownRun` names the marker's job id, which the browser sends only after the person confirms; `task.clearRun` clears the marker on its own. A job id that no longer matches the marker is refused, so a confirmation never clears a run the person was not shown.\n\n## Data and storage\n\n- **Location:** `<project root>/.dsh/tasks.db`. The directory is created `0700` and the file `0600`; an existing file keeps its mode.\n- **Tables:** `tasks`, `comments`, `activity` (per-change history), `meta` (`revision`, `next_ref`), and a `board` view for reading by hand:\n\n```bash\nsqlite3 .dsh/tasks.db \"select card, title, status, assignee from board where state = 'active'\"\n```\n\n- **`ref`** comes from `meta.next_ref` and is never reused, including after a delete.\n- **`rank`** is a fractional-index string, so a drag writes one row.\n- **`meta.revision`** is advanced by triggers on `tasks` and `comments`, so every writer moves it, including `sqlite3`.\n- **Sharing:** several `dsh` processes on one host can use the same board. Each process keeps one handle per database file. Do not run two `dsh` servers against the same `$DSH_HOME`.\n- **Backups:** SQLite's online backup works while `dsh` is running:\n\n```bash\nsqlite3 .dsh/tasks.db \".backup tasks-backup.db\"\n```\n\n### Upgrading an existing board\n\nThe layout version is stored in `PRAGMA user_version`; this build writes version **3**. Boards created by the published 0.2.2 and earlier are version 1; version 2 was only ever written by unreleased development builds. The first time this build opens an older board, it upgrades the file in place, in one transaction: it adds the `tasks.run_owner` column (from version 1), installs the revision triggers and the running-marker guard trigger, and recreates the `board` view. No rows are dropped or rewritten, and no running marker is cleared by the upgrade.\n\nCopy the file aside before the first start, because the upgrade is one-way:\n\n```bash\ncp .dsh/tasks.db .dsh/tasks.v1-backup.db\n```\n\nAfter the upgrade:\n\n- An older build process that already had the board open keeps working and its writes still move the revision. An older build that opens the file afterwards refuses it, because it only reads version 1. A file stamped with a version newer than this build is refused in the same way.\n- A running marker written by an older build has no owner. It is **kept**, shown as **Running (owner unknown)**, and cleared only when you confirm it on the board (Clear the running marker, Dispatch to agent, or Delete), or when this process's own job registry identifies that run and reports it finished (the older build's run in this same process, before a plugin reload). It is not cleared on open, because the older build may still be running it.\n- If you clear such a marker and dispatch again while the older build's run is in fact still going, that run's eventual settlement is refused by the guard trigger instead of clearing the new run's marker. The older build logs the failed write and carries on; the new run is unaffected. Stop the older process's run from that process if you do not want two runs of the card.\n\n### Run ownership and stale markers\n\nA running card stores `running_job_id` and `run_owner`, a JSON object `{host, machine, pid, processStart, instance, sessionId}`. Markers written by development builds of version 2 have only `{host, pid, instance, sessionId}` and are still read.\n\n- **`instance`** is a random id per `dsh` process. It is checked first: a marker with this process's instance is this process's, even if the host name has changed since.\n- **`machine`** is a salted SHA-256 digest of the machine's stable id: `IOPlatformUUID` on macOS (read once per process with `/usr/sbin/ioreg`), `/etc/machine-id` or `/var/lib/dbus/machine-id` plus the pid namespace on Linux, `MachineGuid` on Windows (read once with `reg.exe`). If none can be read, the host name is used instead. `host` is still written, for people reading the row, and is compared only for markers without `machine`.\n- **`processStart`** is the owning process's start: ticks since boot plus the boot id from `/proc` on Linux, the `ps -o lstart` time on macOS (compared within 30 seconds). It is omitted where the platform offers neither, including Windows.\n\nA process clears a marker only when:\n\n- its owner is on this machine, and the owner process has exited, or its pid is now held by a process with a different start time;\n- the marker is this process's own run, and the job registry reports the job settled or no longer knows it; or\n- the marker has no owner, and either you confirmed clearing it on the board, or this process's job registry holds a `task` job with the same id, for the same card and dispatching session, started within 10 seconds of the recorded dispatch, and that job has finished.\n\nMarkers from another live process are left alone, as are markers whose owner start time cannot be read. **Markers owned on another machine are never cleared automatically.** To clear one by hand (the board picks it up on the next poll), clear both columns in one statement; a statement that clears `running_job_id` of an owned marker alone is refused by the guard trigger:\n\n```bash\nsqlite3 .dsh/tasks.db \"UPDATE tasks SET running_job_id = NULL, run_owner = NULL WHERE ref = 12\"\n```\n\n## Security and trust model\n\n- **Git reads are hardened.** The assignee picker runs `git --no-pager -c log.showSignature=false -c core.fsmonitor=false -c core.pager=cat -C <root> log --no-show-signature …`, plus two `git config --get` calls, with a 5-second timeout and a 4 MB output cap. A repository's own `.git/config` cannot make opening the board run `gpg.program` or an fsmonitor hook. Nothing is written to git. Results are cached per project for 60 seconds.\n- **Runs are stopped as their owner.** **Stop** on a job the session can see acts as that session, the same as `job_kill`. A card's run started by another session in this process is stopped as its owning session, and only if the job's kind is `task`. A hand-edited `running_job_id` that points at someone's shell job cannot be used to stop that job.\n- **Deletes respect other processes.** A card whose run belongs to another live process cannot be deleted from this one. A card whose run has no recorded owner is deleted only after you confirm.\n- **Owner checks run fixed system tools.** Besides `git`, the host may run `/usr/sbin/ioreg` (macOS) or `reg.exe` (Windows) once per process to read the machine id, and `/bin/ps -o lstart= -p <pid>` (macOS) when judging another live process's marker on this machine. Each runs without a shell, from an absolute path, with a 2-second timeout; the only value taken from the board is the pid, which must be a positive integer. On Linux only files under `/proc`, `/etc`, and `/var/lib/dbus` are read. The machine id is stored only as a salted digest.\n- **The model cannot delete by default.** `task_delete` is only registered with `allowDelete: true`.\n- **Job output is not taken from the agent.** The board reads output only for its own `task` jobs, which return final output without consuming the agent's read cursor.\n\n## Known limitations\n\n- **Markers owned on another machine are never auto-cleared.** See [Run ownership](#run-ownership-and-stale-markers).\n- **Markers written by an older build are never auto-cleared** unless this process's job registry identifies the run as finished. Clearing one is your call on the board.\n- **Machines with a cloned machine id** (for example VM images that were not re-sealed) look like one machine, so a marker from the other could be swept when its pid is not found locally. Linux containers are told apart by pid namespace.\n- **Dispatch needs a live session.** A tab on a session that is no longer live can read and edit the board but cannot dispatch.\n- **Board state is not in the session log.** An out-of-tree plugin cannot add session event types, so history lives only in `tasks.db`.\n\n## Development\n\nThe `devDependencies` link a `deepseek-harness` checkout at `../../deepseek-harness`, relative to this repository, for types and tests. `pnpm install` expects it there.\n\n```bash\npnpm install\npnpm run typecheck\npnpm test\npnpm run build        # tsc for declarations, then tsdown for the node and browser bundles\n```\n\nThere is no Typert contract to regenerate: the channel's payloads are validated in `src/domain/validate.ts` and `src/host/index.ts`.\n\nTo run a checkout in a local profile, add it by path and restart the web server:\n\n```bash\ndsh plugin --profile web add link:/absolute/path/to/dsh-tasks-manager\ndsh web\n```\n\nA linked package resolves its imports from its own directory, so the harness packages it imports must resolve there to the same copies the running harness uses. The maintainers' workspace does this with `publish-plugins.sh` and `.dsh-compat/install-plugins.sh` in the parent `dsh-plugins` directory, not in this repository. After a rebuild, restart `dsh web`.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}