prjct-cli 0.28.4 → 0.29.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -161
- package/CLAUDE.md +170 -0
- package/README.md +14 -1
- package/assets/statusline/components/changes.sh +10 -0
- package/assets/statusline/components/context.sh +31 -0
- package/assets/statusline/components/dir.sh +11 -0
- package/assets/statusline/components/git.sh +45 -0
- package/assets/statusline/components/linear.sh +74 -0
- package/assets/statusline/components/model.sh +12 -0
- package/assets/statusline/components/prjct_icon.sh +9 -0
- package/assets/statusline/components/task.sh +40 -0
- package/assets/statusline/default-config.json +46 -0
- package/assets/statusline/lib/cache.sh +119 -0
- package/assets/statusline/lib/config.sh +147 -0
- package/assets/statusline/lib/theme.sh +169 -0
- package/assets/statusline/statusline.sh +121 -0
- package/assets/statusline/themes/default.json +27 -0
- package/core/agentic/agent-router.ts +0 -15
- package/core/agentic/command-executor.ts +5 -53
- package/core/agentic/index.ts +1 -11
- package/core/agentic/memory-system.ts +5 -44
- package/core/agentic/prompt-builder.ts +2 -83
- package/core/agentic/smart-context.ts +64 -36
- package/core/agentic/template-loader.ts +32 -107
- package/core/commands/command-data.ts +33 -0
- package/core/commands/commands.ts +12 -4
- package/core/commands/registry.ts +37 -0
- package/core/domain/agent-loader.ts +9 -7
- package/core/domain/context-estimator.ts +15 -15
- package/core/index.ts +2 -0
- package/core/infrastructure/config-manager.ts +4 -25
- package/core/infrastructure/path-manager.ts +7 -7
- package/core/infrastructure/setup.ts +182 -86
- package/core/integrations/issue-tracker/enricher.ts +281 -0
- package/core/integrations/issue-tracker/index.ts +8 -0
- package/core/integrations/issue-tracker/manager.ts +284 -0
- package/core/integrations/issue-tracker/types.ts +321 -0
- package/core/integrations/linear/client.ts +375 -0
- package/core/integrations/linear/index.ts +6 -0
- package/core/integrations/notion/client.ts +413 -0
- package/core/integrations/notion/index.ts +46 -0
- package/core/integrations/notion/setup.ts +235 -0
- package/core/integrations/notion/sync.ts +818 -0
- package/core/integrations/notion/templates.ts +246 -0
- package/core/plugin/builtin/notion.ts +178 -0
- package/core/schemas/enriched-task.ts +278 -0
- package/core/schemas/outcomes.ts +471 -14
- package/core/schemas/prd.ts +437 -0
- package/core/schemas/roadmap.ts +188 -4
- package/core/server/index.ts +1 -0
- package/core/server/routes-extended.ts +544 -0
- package/core/server/server.ts +10 -0
- package/core/session/session-log-manager.ts +0 -17
- package/core/types/config.ts +1 -1
- package/core/types/index.ts +2 -0
- package/core/types/integrations.ts +56 -20
- package/core/types/storage.ts +8 -0
- package/core/types/task.ts +4 -0
- package/dist/bin/prjct.mjs +1457 -765
- package/package.json +3 -1
- package/packages/shared/node_modules/@types/bun/LICENSE +21 -0
- package/packages/shared/node_modules/@types/bun/README.md +20 -0
- package/packages/shared/node_modules/@types/bun/index.d.ts +1 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/CLAUDE.md +105 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/README.md +33 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/bun.d.ts +7032 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/bun.ns.d.ts +5 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/bundle.d.ts +74 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/deprecated.d.ts +184 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/devserver.d.ts +187 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/README.md +28 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/bundler/bytecode.mdx +465 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/bundler/css.mdx +1024 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/bundler/esbuild.mdx +298 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/bundler/executables.mdx +1277 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/bundler/fullstack.mdx +1086 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/bundler/hot-reloading.mdx +229 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/bundler/html-static.mdx +488 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/bundler/index.mdx +1604 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/bundler/loaders.mdx +451 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/bundler/macros.mdx +328 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/bundler/minifier.mdx +1286 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/bundler/plugins.mdx +425 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/feedback.mdx +75 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/binary/arraybuffer-to-array.mdx +29 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/binary/arraybuffer-to-blob.mdx +26 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/binary/arraybuffer-to-buffer.mdx +27 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/binary/arraybuffer-to-string.mdx +17 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/binary/arraybuffer-to-typedarray.mdx +41 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/binary/blob-to-arraybuffer.mdx +16 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/binary/blob-to-dataview.mdx +16 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/binary/blob-to-stream.mdx +16 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/binary/blob-to-string.mdx +17 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/binary/blob-to-typedarray.mdx +16 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/binary/buffer-to-arraybuffer.mdx +16 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/binary/buffer-to-blob.mdx +16 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/binary/buffer-to-readablestream.mdx +43 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/binary/buffer-to-string.mdx +27 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/binary/buffer-to-typedarray.mdx +16 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/binary/dataview-to-string.mdx +17 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/binary/typedarray-to-arraybuffer.mdx +27 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/binary/typedarray-to-blob.mdx +18 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/binary/typedarray-to-buffer.mdx +16 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/binary/typedarray-to-dataview.mdx +16 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/binary/typedarray-to-readablestream.mdx +43 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/binary/typedarray-to-string.mdx +18 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/deployment/aws-lambda.mdx +204 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/deployment/digital-ocean.mdx +161 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/deployment/google-cloud-run.mdx +194 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/deployment/railway.mdx +145 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/deployment/render.mdx +82 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/deployment/vercel.mdx +97 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/ecosystem/astro.mdx +82 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/ecosystem/discordjs.mdx +80 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/ecosystem/docker.mdx +151 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/ecosystem/drizzle.mdx +195 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/ecosystem/elysia.mdx +31 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/ecosystem/express.mdx +43 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/ecosystem/gel.mdx +261 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/ecosystem/hono.mdx +47 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/ecosystem/mongoose.mdx +92 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/ecosystem/neon-drizzle.mdx +234 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/ecosystem/neon-serverless-postgres.mdx +60 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/ecosystem/nextjs.mdx +103 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/ecosystem/nuxt.mdx +96 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/ecosystem/pm2.mdx +55 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/ecosystem/prisma-postgres.mdx +169 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/ecosystem/prisma.mdx +164 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/ecosystem/qwik.mdx +114 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/ecosystem/react.mdx +52 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/ecosystem/remix.mdx +97 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/ecosystem/sentry.mdx +54 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/ecosystem/solidstart.mdx +62 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/ecosystem/ssr-react.mdx +49 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/ecosystem/stric.mdx +54 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/ecosystem/sveltekit.mdx +138 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/ecosystem/systemd.mdx +114 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/ecosystem/tanstack-start.mdx +791 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/ecosystem/upstash.mdx +87 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/ecosystem/vite.mdx +77 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/html-rewriter/extract-links.mdx +71 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/html-rewriter/extract-social-meta.mdx +97 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/http/cluster.mdx +69 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/http/fetch-unix.mdx +35 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/http/fetch.mdx +26 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/http/file-uploads.mdx +97 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/http/hot.mdx +28 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/http/proxy.mdx +50 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/http/server.mdx +48 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/http/simple.mdx +20 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/http/stream-file.mdx +50 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/http/stream-iterator.mdx +49 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/http/stream-node-streams-in-bun.mdx +22 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/http/tls.mdx +32 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/index.mdx +10 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/install/add-dev.mdx +28 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/install/add-git.mdx +40 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/install/add-optional.mdx +27 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/install/add-peer.mdx +45 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/install/add-tarball.mdx +35 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/install/add.mdx +44 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/install/azure-artifacts.mdx +76 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/install/cicd.mdx +43 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/install/custom-registry.mdx +32 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/install/from-npm-install-to-bun-install.mdx +230 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/install/git-diff-bun-lockfile.mdx +48 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/install/jfrog-artifactory.mdx +28 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/install/npm-alias.mdx +25 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/install/registry-scope.mdx +40 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/install/trusted.mdx +52 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/install/workspaces.mdx +70 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/install/yarnlock.mdx +51 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/process/argv.mdx +66 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/process/ctrl-c.mdx +18 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/process/ipc.mdx +69 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/process/nanoseconds.mdx +15 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/process/os-signals.mdx +31 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/process/spawn-stderr.mdx +34 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/process/spawn-stdout.mdx +28 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/process/spawn.mdx +43 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/process/stdin.mdx +62 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/read-file/arraybuffer.mdx +30 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/read-file/buffer.mdx +21 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/read-file/exists.mdx +18 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/read-file/json.mdx +19 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/read-file/mime.mdx +22 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/read-file/stream.mdx +28 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/read-file/string.mdx +24 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/read-file/uint8array.mdx +23 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/read-file/watch.mdx +66 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/runtime/build-time-constants.mdx +295 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/runtime/cicd.mdx +45 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/runtime/codesign-macos-executable.mdx +61 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/runtime/define-constant.mdx +149 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/runtime/delete-directory.mdx +39 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/runtime/delete-file.mdx +21 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/runtime/heap-snapshot.mdx +28 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/runtime/import-html.mdx +15 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/runtime/import-json.mdx +46 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/runtime/import-toml.mdx +32 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/runtime/import-yaml.mdx +104 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/runtime/read-env.mdx +37 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/runtime/set-env.mdx +51 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/runtime/shell.mdx +42 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/runtime/timezone.mdx +38 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/runtime/tsconfig-paths.mdx +31 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/runtime/typescript.mdx +51 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/runtime/vscode-debugger.mdx +47 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/runtime/web-debugger.mdx +103 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/streams/node-readable-to-arraybuffer.mdx +13 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/streams/node-readable-to-blob.mdx +13 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/streams/node-readable-to-json.mdx +14 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/streams/node-readable-to-string.mdx +14 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/streams/node-readable-to-uint8array.mdx +13 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/streams/to-array.mdx +16 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/streams/to-arraybuffer.mdx +16 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/streams/to-blob.mdx +16 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/streams/to-buffer.mdx +17 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/streams/to-json.mdx +16 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/streams/to-string.mdx +16 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/streams/to-typedarray.mdx +24 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/test/bail.mdx +24 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/test/concurrent-test-glob.mdx +146 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/test/coverage-threshold.mdx +67 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/test/coverage.mdx +49 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/test/happy-dom.mdx +73 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/test/migrate-from-jest.mdx +125 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/test/mock-clock.mdx +50 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/test/mock-functions.mdx +70 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/test/rerun-each.mdx +16 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/test/run-tests.mdx +116 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/test/skip-tests.mdx +43 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/test/snapshot.mdx +102 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/test/spy-on.mdx +49 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/test/svelte-test.mdx +113 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/test/testing-library.mdx +93 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/test/timeout.mdx +17 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/test/todo-tests.mdx +74 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/test/update-snapshots.mdx +49 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/test/watch-mode.mdx +24 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/util/base64.mdx +17 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/util/deep-equals.mdx +41 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/util/deflate.mdx +20 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/util/detect-bun.mdx +28 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/util/entrypoint.mdx +19 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/util/escape-html.mdx +24 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/util/file-url-to-path.mdx +16 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/util/gzip.mdx +20 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/util/hash-a-password.mdx +56 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/util/import-meta-dir.mdx +15 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/util/import-meta-file.mdx +15 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/util/import-meta-path.mdx +15 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/util/javascript-uuid.mdx +25 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/util/main.mdx +43 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/util/path-to-file-url.mdx +16 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/util/sleep.mdx +24 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/util/upgrade.mdx +93 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/util/version.mdx +23 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/util/which-path-to-executable-bin.mdx +17 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/websocket/compression.mdx +33 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/websocket/context.mdx +79 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/websocket/pubsub.mdx +43 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/websocket/simple.mdx +38 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/write-file/append.mdx +54 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/write-file/basic.mdx +46 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/write-file/blob.mdx +30 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/write-file/cat.mdx +19 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/write-file/file-cp.mdx +18 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/write-file/filesink.mdx +54 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/write-file/response.mdx +19 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/write-file/stdout.mdx +23 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/write-file/stream.mdx +19 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/guides/write-file/unlink.mdx +18 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/index.mdx +133 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/installation.mdx +365 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/pm/bunx.mdx +91 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/pm/catalogs.mdx +292 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/pm/cli/add.mdx +179 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/pm/cli/audit.mdx +60 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/pm/cli/info.mdx +70 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/pm/cli/install.mdx +606 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/pm/cli/link.mdx +61 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/pm/cli/outdated.mdx +197 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/pm/cli/patch.mdx +69 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/pm/cli/pm.mdx +323 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/pm/cli/publish.mdx +131 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/pm/cli/remove.mdx +16 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/pm/cli/update.mdx +140 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/pm/cli/why.mdx +84 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/pm/filter.mdx +102 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/pm/global-cache.mdx +72 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/pm/isolated-installs.mdx +220 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/pm/lifecycle.mdx +64 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/pm/lockfile.mdx +64 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/pm/npmrc.mdx +111 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/pm/overrides.mdx +83 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/pm/scopes-registries.mdx +35 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/pm/security-scanner-api.mdx +95 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/pm/workspaces.mdx +115 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/project/benchmarking.mdx +241 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/project/bindgen.mdx +223 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/project/building-windows.mdx +133 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/project/contributing.mdx +388 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/project/feedback.mdx +20 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/project/license.mdx +78 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/project/roadmap.mdx +8 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/quickstart.mdx +251 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/auto-install.mdx +97 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/binary-data.mdx +846 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/bun-apis.mdx +59 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/bunfig.mdx +723 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/c-compiler.mdx +204 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/child-process.mdx +659 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/color.mdx +267 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/console.mdx +67 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/cookies.mdx +454 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/debugger.mdx +335 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/environment-variables.mdx +231 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/ffi.mdx +565 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/file-io.mdx +306 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/file-system-router.mdx +118 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/file-types.mdx +435 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/glob.mdx +181 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/globals.mdx +72 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/hashing.mdx +315 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/html-rewriter.mdx +333 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/http/cookies.mdx +79 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/http/error-handling.mdx +40 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/http/metrics.mdx +36 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/http/routing.mdx +289 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/http/server.mdx +645 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/http/tls.mdx +101 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/http/websockets.mdx +414 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/index.mdx +223 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/jsx.mdx +115 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/module-resolution.mdx +374 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/networking/dns.mdx +111 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/networking/fetch.mdx +484 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/networking/tcp.mdx +239 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/networking/udp.mdx +129 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/node-api.mdx +19 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/nodejs-compat.mdx +468 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/plugins.mdx +419 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/redis.mdx +583 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/s3.mdx +863 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/secrets.mdx +340 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/semver.mdx +57 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/shell.mdx +637 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/sql.mdx +1404 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/sqlite.mdx +721 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/streams.mdx +232 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/templating/create.mdx +269 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/templating/init.mdx +58 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/transpiler.mdx +288 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/typescript.mdx +58 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/utils.mdx +922 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/watch-mode.mdx +161 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/web-apis.mdx +29 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/workers.mdx +314 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/runtime/yaml.mdx +469 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/snippets/cli/add.mdx +166 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/snippets/cli/build.mdx +196 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/snippets/cli/bunx.mdx +49 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/snippets/cli/feedback.mdx +17 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/snippets/cli/init.mdx +84 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/snippets/cli/install.mdx +173 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/snippets/cli/link.mdx +163 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/snippets/cli/outdated.mdx +140 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/snippets/cli/patch.mdx +171 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/snippets/cli/publish.mdx +198 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/snippets/cli/remove.mdx +146 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/snippets/cli/run.mdx +293 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/snippets/cli/test.mdx +100 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/snippets/cli/update.mdx +144 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/test/code-coverage.mdx +409 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/test/configuration.mdx +514 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/test/dates-times.mdx +129 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/test/discovery.mdx +90 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/test/dom.mdx +226 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/test/index.mdx +380 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/test/lifecycle.mdx +366 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/test/mocks.mdx +637 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/test/reporters.mdx +126 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/test/runtime-behavior.mdx +342 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/test/snapshots.mdx +434 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/test/writing-tests.mdx +672 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/docs/typescript.mdx +54 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/extensions.d.ts +35 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/fetch.d.ts +79 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/ffi.d.ts +1154 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/globals.d.ts +2067 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/html-rewriter.d.ts +186 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/index.d.ts +32 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/jsc.d.ts +233 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/overrides.d.ts +376 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/package.json +37 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/redis.d.ts +3352 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/s3.d.ts +1299 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/security.d.ts +101 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/serve.d.ts +1296 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/shell.d.ts +380 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/sql.d.ts +887 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/sqlite.d.ts +1321 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/test-globals.d.ts +22 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/test.d.ts +2391 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/vendor/expect-type/branding.d.ts +283 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/vendor/expect-type/index.d.ts +1207 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/vendor/expect-type/messages.d.ts +395 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/vendor/expect-type/overloads.d.ts +669 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/vendor/expect-type/utils.d.ts +431 -0
- package/packages/shared/node_modules/@types/bun/node_modules/bun-types/wasm.d.ts +193 -0
- package/packages/shared/node_modules/@types/bun/package.json +53 -0
- package/scripts/postinstall.js +69 -0
- package/templates/agentic/agents/uxui.md +218 -0
- package/templates/agentic/subagent-generation.md +81 -241
- package/templates/commands/bug.md +392 -51
- package/templates/commands/cleanup.md +0 -5
- package/templates/commands/dashboard.md +686 -0
- package/templates/commands/done.md +232 -53
- package/templates/commands/enrich.md +345 -0
- package/templates/commands/feature.md +46 -0
- package/templates/commands/impact.md +864 -0
- package/templates/commands/init.md +44 -1
- package/templates/commands/linear.md +287 -0
- package/templates/commands/now.md +53 -0
- package/templates/commands/p.md +1 -1
- package/templates/commands/plan.md +696 -0
- package/templates/commands/prd.md +356 -0
- package/templates/commands/ship.md +589 -87
- package/templates/commands/sync.md +766 -180
- package/templates/commands/task.md +333 -51
- package/templates/context/dashboard.md +256 -0
- package/templates/context/roadmap.md +221 -0
- package/templates/global/CLAUDE.md +161 -101
- package/templates/mcp-config.json +46 -23
- package/templates/skills/notion-push.md +116 -0
- package/templates/skills/notion-setup.md +199 -0
- package/templates/skills/notion-sync.md +290 -0
- package/templates/subagents/domain/backend.md +106 -0
- package/templates/subagents/domain/database.md +118 -0
- package/templates/subagents/domain/devops.md +149 -0
- package/templates/subagents/domain/frontend.md +100 -0
- package/templates/subagents/domain/testing.md +166 -0
- package/templates/subagents/pm-expert.md +366 -0
- package/templates/subagents/workflow/chief-architect.md +657 -0
- package/core/agentic/token-estimator.ts +0 -264
- package/core/infrastructure/slash-command-registry.ts +0 -176
- package/templates/commands/setup-statusline.md +0 -138
- package/templates/guides/agent-generation.md +0 -164
- package/templates/guides/claude-code-ux.md +0 -232
- package/templates/guides/integrations.md +0 -149
- package/templates/shared/git-operations.md +0 -68
- package/templates/shared/io-patterns.md +0 -72
- package/templates/shared/standard.md +0 -70
- package/templates/shared/validation.md +0 -75
package/dist/bin/prjct.mjs
CHANGED
|
@@ -10,10 +10,10 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
|
10
10
|
var __getProtoOf = Object.getPrototypeOf;
|
|
11
11
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
12
12
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
13
|
-
var __glob = (map) => (
|
|
14
|
-
var fn = map[
|
|
13
|
+
var __glob = (map) => (path33) => {
|
|
14
|
+
var fn = map[path33];
|
|
15
15
|
if (fn) return fn();
|
|
16
|
-
throw new Error("Module not found in bundle: " +
|
|
16
|
+
throw new Error("Module not found in bundle: " + path33);
|
|
17
17
|
};
|
|
18
18
|
var __esm = (fn, res) => function __init() {
|
|
19
19
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
@@ -277,7 +277,7 @@ function formatDuration(milliseconds) {
|
|
|
277
277
|
}
|
|
278
278
|
return `${seconds}s`;
|
|
279
279
|
}
|
|
280
|
-
function
|
|
280
|
+
function calculateDuration2(startDate, endDate = /* @__PURE__ */ new Date()) {
|
|
281
281
|
const milliseconds = endDate.getTime() - startDate.getTime();
|
|
282
282
|
return formatDuration(milliseconds);
|
|
283
283
|
}
|
|
@@ -308,7 +308,7 @@ var init_date_helper = __esm({
|
|
|
308
308
|
__name(isToday, "isToday");
|
|
309
309
|
__name(isWithinLastDays, "isWithinLastDays");
|
|
310
310
|
__name(formatDuration, "formatDuration");
|
|
311
|
-
__name(
|
|
311
|
+
__name(calculateDuration2, "calculateDuration");
|
|
312
312
|
__name(getStartOfDay, "getStartOfDay");
|
|
313
313
|
__name(getEndOfDay, "getEndOfDay");
|
|
314
314
|
date_helper_default = {
|
|
@@ -325,7 +325,7 @@ var init_date_helper = __esm({
|
|
|
325
325
|
isToday,
|
|
326
326
|
isWithinLastDays,
|
|
327
327
|
formatDuration,
|
|
328
|
-
calculateDuration,
|
|
328
|
+
calculateDuration: calculateDuration2,
|
|
329
329
|
getStartOfDay,
|
|
330
330
|
getEndOfDay
|
|
331
331
|
};
|
|
@@ -370,11 +370,11 @@ __export(file_helper_exports, {
|
|
|
370
370
|
writeJson: () => writeJson,
|
|
371
371
|
writeLines: () => writeLines
|
|
372
372
|
});
|
|
373
|
-
import
|
|
374
|
-
import
|
|
373
|
+
import fs5 from "fs/promises";
|
|
374
|
+
import path5 from "path";
|
|
375
375
|
async function readJson(filePath, defaultValue = null) {
|
|
376
376
|
try {
|
|
377
|
-
const content = await
|
|
377
|
+
const content = await fs5.readFile(filePath, "utf-8");
|
|
378
378
|
return JSON.parse(content);
|
|
379
379
|
} catch (error) {
|
|
380
380
|
if (isNotFoundError(error)) {
|
|
@@ -385,11 +385,11 @@ async function readJson(filePath, defaultValue = null) {
|
|
|
385
385
|
}
|
|
386
386
|
async function writeJson(filePath, data, indent = 2) {
|
|
387
387
|
const content = JSON.stringify(data, null, indent);
|
|
388
|
-
await
|
|
388
|
+
await fs5.writeFile(filePath, content, "utf-8");
|
|
389
389
|
}
|
|
390
390
|
async function readFile(filePath, defaultValue = "") {
|
|
391
391
|
try {
|
|
392
|
-
return await
|
|
392
|
+
return await fs5.readFile(filePath, "utf-8");
|
|
393
393
|
} catch (error) {
|
|
394
394
|
if (isNotFoundError(error)) {
|
|
395
395
|
return defaultValue;
|
|
@@ -398,32 +398,32 @@ async function readFile(filePath, defaultValue = "") {
|
|
|
398
398
|
}
|
|
399
399
|
}
|
|
400
400
|
async function writeFile(filePath, content) {
|
|
401
|
-
const dir =
|
|
402
|
-
await
|
|
403
|
-
await
|
|
401
|
+
const dir = path5.dirname(filePath);
|
|
402
|
+
await fs5.mkdir(dir, { recursive: true });
|
|
403
|
+
await fs5.writeFile(filePath, content, "utf-8");
|
|
404
404
|
}
|
|
405
405
|
async function atomicWrite(filePath, content) {
|
|
406
|
-
const dir =
|
|
407
|
-
await
|
|
406
|
+
const dir = path5.dirname(filePath);
|
|
407
|
+
await fs5.mkdir(dir, { recursive: true });
|
|
408
408
|
const tempPath = `${filePath}.${Date.now()}.tmp`;
|
|
409
|
-
await
|
|
410
|
-
await
|
|
409
|
+
await fs5.writeFile(tempPath, content, "utf-8");
|
|
410
|
+
await fs5.rename(tempPath, filePath);
|
|
411
411
|
}
|
|
412
412
|
async function appendToFile(filePath, content) {
|
|
413
|
-
await
|
|
413
|
+
await fs5.appendFile(filePath, content, "utf-8");
|
|
414
414
|
}
|
|
415
415
|
async function appendLine(filePath, line) {
|
|
416
|
-
const dir =
|
|
417
|
-
await
|
|
418
|
-
await
|
|
416
|
+
const dir = path5.dirname(filePath);
|
|
417
|
+
await fs5.mkdir(dir, { recursive: true });
|
|
418
|
+
await fs5.appendFile(filePath, line + "\n", "utf-8");
|
|
419
419
|
}
|
|
420
420
|
async function prependToFile(filePath, content) {
|
|
421
421
|
try {
|
|
422
|
-
const existing = await
|
|
423
|
-
await
|
|
422
|
+
const existing = await fs5.readFile(filePath, "utf-8");
|
|
423
|
+
await fs5.writeFile(filePath, content + existing, "utf-8");
|
|
424
424
|
} catch (error) {
|
|
425
425
|
if (isNotFoundError(error)) {
|
|
426
|
-
await
|
|
426
|
+
await fs5.writeFile(filePath, content, "utf-8");
|
|
427
427
|
} else {
|
|
428
428
|
throw error;
|
|
429
429
|
}
|
|
@@ -431,7 +431,7 @@ async function prependToFile(filePath, content) {
|
|
|
431
431
|
}
|
|
432
432
|
async function fileExists(filePath) {
|
|
433
433
|
try {
|
|
434
|
-
await
|
|
434
|
+
await fs5.access(filePath);
|
|
435
435
|
return true;
|
|
436
436
|
} catch {
|
|
437
437
|
return false;
|
|
@@ -439,18 +439,18 @@ async function fileExists(filePath) {
|
|
|
439
439
|
}
|
|
440
440
|
async function dirExists(dirPath) {
|
|
441
441
|
try {
|
|
442
|
-
const stats = await
|
|
442
|
+
const stats = await fs5.stat(dirPath);
|
|
443
443
|
return stats.isDirectory();
|
|
444
444
|
} catch {
|
|
445
445
|
return false;
|
|
446
446
|
}
|
|
447
447
|
}
|
|
448
448
|
async function ensureDir(dirPath) {
|
|
449
|
-
await
|
|
449
|
+
await fs5.mkdir(dirPath, { recursive: true });
|
|
450
450
|
}
|
|
451
451
|
async function deleteFile(filePath) {
|
|
452
452
|
try {
|
|
453
|
-
await
|
|
453
|
+
await fs5.unlink(filePath);
|
|
454
454
|
return true;
|
|
455
455
|
} catch (error) {
|
|
456
456
|
if (isNotFoundError(error)) {
|
|
@@ -461,7 +461,7 @@ async function deleteFile(filePath) {
|
|
|
461
461
|
}
|
|
462
462
|
async function deleteDir(dirPath) {
|
|
463
463
|
try {
|
|
464
|
-
await
|
|
464
|
+
await fs5.rm(dirPath, { recursive: true, force: true });
|
|
465
465
|
return true;
|
|
466
466
|
} catch (error) {
|
|
467
467
|
if (isNotFoundError(error)) {
|
|
@@ -472,7 +472,7 @@ async function deleteDir(dirPath) {
|
|
|
472
472
|
}
|
|
473
473
|
async function listFiles(dirPath, options = {}) {
|
|
474
474
|
try {
|
|
475
|
-
const entries = await
|
|
475
|
+
const entries = await fs5.readdir(dirPath, { withFileTypes: true });
|
|
476
476
|
let files = entries;
|
|
477
477
|
if (options.filesOnly) {
|
|
478
478
|
files = files.filter((entry) => entry.isFile());
|
|
@@ -492,18 +492,18 @@ async function listFiles(dirPath, options = {}) {
|
|
|
492
492
|
}
|
|
493
493
|
}
|
|
494
494
|
async function getFileSize(filePath) {
|
|
495
|
-
const stats = await
|
|
495
|
+
const stats = await fs5.stat(filePath);
|
|
496
496
|
return stats.size;
|
|
497
497
|
}
|
|
498
498
|
async function getFileModifiedTime(filePath) {
|
|
499
|
-
const stats = await
|
|
499
|
+
const stats = await fs5.stat(filePath);
|
|
500
500
|
return stats.mtime;
|
|
501
501
|
}
|
|
502
502
|
async function copyFile(sourcePath, destPath) {
|
|
503
|
-
await
|
|
503
|
+
await fs5.copyFile(sourcePath, destPath);
|
|
504
504
|
}
|
|
505
505
|
async function moveFile(oldPath, newPath) {
|
|
506
|
-
await
|
|
506
|
+
await fs5.rename(oldPath, newPath);
|
|
507
507
|
}
|
|
508
508
|
async function readLines(filePath) {
|
|
509
509
|
const content = await readFile(filePath, "");
|
|
@@ -514,10 +514,10 @@ async function writeLines(filePath, lines) {
|
|
|
514
514
|
await writeFile(filePath, content);
|
|
515
515
|
}
|
|
516
516
|
function getFileExtension(filePath) {
|
|
517
|
-
return
|
|
517
|
+
return path5.extname(filePath);
|
|
518
518
|
}
|
|
519
519
|
function getFileNameWithoutExtension(filePath) {
|
|
520
|
-
return
|
|
520
|
+
return path5.basename(filePath, path5.extname(filePath));
|
|
521
521
|
}
|
|
522
522
|
var file_helper_default;
|
|
523
523
|
var init_file_helper = __esm({
|
|
@@ -574,10 +574,10 @@ var init_file_helper = __esm({
|
|
|
574
574
|
});
|
|
575
575
|
|
|
576
576
|
// core/infrastructure/path-manager.ts
|
|
577
|
-
import
|
|
578
|
-
import
|
|
577
|
+
import fs6 from "fs/promises";
|
|
578
|
+
import path6 from "path";
|
|
579
579
|
import crypto2 from "crypto";
|
|
580
|
-
import
|
|
580
|
+
import os3 from "os";
|
|
581
581
|
var PathManager, pathManager, path_manager_default;
|
|
582
582
|
var init_path_manager = __esm({
|
|
583
583
|
"core/infrastructure/path-manager.ts"() {
|
|
@@ -593,9 +593,9 @@ var init_path_manager = __esm({
|
|
|
593
593
|
globalConfigDir;
|
|
594
594
|
constructor() {
|
|
595
595
|
const envOverride = process.env.PRJCT_CLI_HOME?.trim();
|
|
596
|
-
this.globalBaseDir = envOverride ?
|
|
597
|
-
this.globalProjectsDir =
|
|
598
|
-
this.globalConfigDir =
|
|
596
|
+
this.globalBaseDir = envOverride ? path6.resolve(envOverride) : path6.join(os3.homedir(), ".prjct-cli");
|
|
597
|
+
this.globalProjectsDir = path6.join(this.globalBaseDir, "projects");
|
|
598
|
+
this.globalConfigDir = path6.join(this.globalBaseDir, "config");
|
|
599
599
|
}
|
|
600
600
|
/**
|
|
601
601
|
* Override global storage location (primarily for tests and sandboxed environments).
|
|
@@ -605,9 +605,9 @@ var init_path_manager = __esm({
|
|
|
605
605
|
* @param {string} globalBaseDir - Base directory that will contain `projects/` and `config/`.
|
|
606
606
|
*/
|
|
607
607
|
setGlobalBaseDir(globalBaseDir) {
|
|
608
|
-
this.globalBaseDir =
|
|
609
|
-
this.globalProjectsDir =
|
|
610
|
-
this.globalConfigDir =
|
|
608
|
+
this.globalBaseDir = path6.resolve(globalBaseDir);
|
|
609
|
+
this.globalProjectsDir = path6.join(this.globalBaseDir, "projects");
|
|
610
|
+
this.globalConfigDir = path6.join(this.globalBaseDir, "config");
|
|
611
611
|
}
|
|
612
612
|
/**
|
|
613
613
|
* Generate a unique project ID using UUID.
|
|
@@ -626,26 +626,26 @@ var init_path_manager = __esm({
|
|
|
626
626
|
* Get the global storage path for a project
|
|
627
627
|
*/
|
|
628
628
|
getGlobalProjectPath(projectId) {
|
|
629
|
-
return
|
|
629
|
+
return path6.join(this.globalProjectsDir, projectId);
|
|
630
630
|
}
|
|
631
631
|
/**
|
|
632
632
|
* Get the local config file path for a project
|
|
633
633
|
*/
|
|
634
634
|
getLocalConfigPath(projectPath) {
|
|
635
|
-
return
|
|
635
|
+
return path6.join(projectPath, ".prjct", "prjct.config.json");
|
|
636
636
|
}
|
|
637
637
|
/**
|
|
638
638
|
* Get the global config file path for a project
|
|
639
639
|
* This file stores authors and other system data that shouldn't be versioned
|
|
640
640
|
*/
|
|
641
641
|
getGlobalProjectConfigPath(projectId) {
|
|
642
|
-
return
|
|
642
|
+
return path6.join(this.getGlobalProjectPath(projectId), "project.json");
|
|
643
643
|
}
|
|
644
644
|
/**
|
|
645
645
|
* Get the legacy .prjct directory path
|
|
646
646
|
*/
|
|
647
647
|
getLegacyPrjctPath(projectPath) {
|
|
648
|
-
return
|
|
648
|
+
return path6.join(projectPath, ".prjct");
|
|
649
649
|
}
|
|
650
650
|
/**
|
|
651
651
|
* Check if a project has legacy .prjct directory
|
|
@@ -679,10 +679,10 @@ var init_path_manager = __esm({
|
|
|
679
679
|
const projectPath = this.getGlobalProjectPath(projectId);
|
|
680
680
|
const layers = ["core", "progress", "planning", "analysis", "memory", "agents"];
|
|
681
681
|
for (const layer of layers) {
|
|
682
|
-
await ensureDir(
|
|
682
|
+
await ensureDir(path6.join(projectPath, layer));
|
|
683
683
|
}
|
|
684
|
-
await ensureDir(
|
|
685
|
-
await ensureDir(
|
|
684
|
+
await ensureDir(path6.join(projectPath, "planning", "tasks"));
|
|
685
|
+
await ensureDir(path6.join(projectPath, "sessions"));
|
|
686
686
|
return projectPath;
|
|
687
687
|
}
|
|
688
688
|
/**
|
|
@@ -691,7 +691,7 @@ var init_path_manager = __esm({
|
|
|
691
691
|
*/
|
|
692
692
|
getSessionPath(projectId, date = /* @__PURE__ */ new Date()) {
|
|
693
693
|
const { year, month, day } = getYearMonthDay(date);
|
|
694
|
-
return
|
|
694
|
+
return path6.join(this.getGlobalProjectPath(projectId), "sessions", year, month, day);
|
|
695
695
|
}
|
|
696
696
|
/**
|
|
697
697
|
* Get current session directory path (today)
|
|
@@ -711,27 +711,27 @@ var init_path_manager = __esm({
|
|
|
711
711
|
* List all session dates for a project
|
|
712
712
|
*/
|
|
713
713
|
async listSessions(projectId, year = null, month = null) {
|
|
714
|
-
const sessionsDir =
|
|
714
|
+
const sessionsDir = path6.join(this.getGlobalProjectPath(projectId), "sessions");
|
|
715
715
|
const sessions = [];
|
|
716
716
|
try {
|
|
717
|
-
const years = await
|
|
717
|
+
const years = await fs6.readdir(sessionsDir, { withFileTypes: true });
|
|
718
718
|
for (const yearEntry of years) {
|
|
719
719
|
if (!yearEntry.isDirectory()) continue;
|
|
720
720
|
if (year && yearEntry.name !== year.toString()) continue;
|
|
721
|
-
const yearPath =
|
|
722
|
-
const months = await
|
|
721
|
+
const yearPath = path6.join(sessionsDir, yearEntry.name);
|
|
722
|
+
const months = await fs6.readdir(yearPath, { withFileTypes: true });
|
|
723
723
|
for (const monthEntry of months) {
|
|
724
724
|
if (!monthEntry.isDirectory()) continue;
|
|
725
725
|
if (month && monthEntry.name !== month.toString().padStart(2, "0")) continue;
|
|
726
|
-
const monthPath =
|
|
727
|
-
const days = await
|
|
726
|
+
const monthPath = path6.join(yearPath, monthEntry.name);
|
|
727
|
+
const days = await fs6.readdir(monthPath, { withFileTypes: true });
|
|
728
728
|
for (const dayEntry of days) {
|
|
729
729
|
if (!dayEntry.isDirectory()) continue;
|
|
730
730
|
sessions.push({
|
|
731
731
|
year: yearEntry.name,
|
|
732
732
|
month: monthEntry.name,
|
|
733
733
|
day: dayEntry.name,
|
|
734
|
-
path:
|
|
734
|
+
path: path6.join(monthPath, dayEntry.name),
|
|
735
735
|
date: /* @__PURE__ */ new Date(`${yearEntry.name}-${monthEntry.name}-${dayEntry.name}`)
|
|
736
736
|
});
|
|
737
737
|
}
|
|
@@ -754,7 +754,7 @@ var init_path_manager = __esm({
|
|
|
754
754
|
* Get the path for a specific file in the global structure
|
|
755
755
|
*/
|
|
756
756
|
getFilePath(projectId, layer, filename) {
|
|
757
|
-
return
|
|
757
|
+
return path6.join(this.getGlobalProjectPath(projectId), layer, filename);
|
|
758
758
|
}
|
|
759
759
|
/**
|
|
760
760
|
* Get all project IDs in global storage
|
|
@@ -762,7 +762,7 @@ var init_path_manager = __esm({
|
|
|
762
762
|
async listProjects() {
|
|
763
763
|
try {
|
|
764
764
|
await this.ensureGlobalStructure();
|
|
765
|
-
const entries = await
|
|
765
|
+
const entries = await fs6.readdir(this.globalProjectsDir, { withFileTypes: true });
|
|
766
766
|
return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
767
767
|
} catch {
|
|
768
768
|
return [];
|
|
@@ -779,7 +779,7 @@ var init_path_manager = __esm({
|
|
|
779
779
|
* Get the relative path from home directory for display
|
|
780
780
|
*/
|
|
781
781
|
getDisplayPath(absolutePath) {
|
|
782
|
-
const homeDir =
|
|
782
|
+
const homeDir = os3.homedir();
|
|
783
783
|
if (absolutePath.startsWith(homeDir)) {
|
|
784
784
|
return absolutePath.replace(homeDir, "~");
|
|
785
785
|
}
|
|
@@ -790,33 +790,33 @@ var init_path_manager = __esm({
|
|
|
790
790
|
* Stored in global config directory, not project-specific
|
|
791
791
|
*/
|
|
792
792
|
getAuthConfigPath() {
|
|
793
|
-
return
|
|
793
|
+
return path6.join(this.globalConfigDir, "auth.json");
|
|
794
794
|
}
|
|
795
795
|
/**
|
|
796
796
|
* Get the sync pending events file path for a project
|
|
797
797
|
*/
|
|
798
798
|
getSyncPendingPath(projectId) {
|
|
799
|
-
return
|
|
799
|
+
return path6.join(this.getGlobalProjectPath(projectId), "sync", "pending.json");
|
|
800
800
|
}
|
|
801
801
|
/**
|
|
802
802
|
* Get the last sync timestamp file path for a project
|
|
803
803
|
*/
|
|
804
804
|
getLastSyncPath(projectId) {
|
|
805
|
-
return
|
|
805
|
+
return path6.join(this.getGlobalProjectPath(projectId), "sync", "last-sync.json");
|
|
806
806
|
}
|
|
807
807
|
/**
|
|
808
808
|
* Get the running status file path (for status signal)
|
|
809
809
|
* Used to indicate when prjct CLI is actively running
|
|
810
810
|
*/
|
|
811
811
|
getRunningStatusPath() {
|
|
812
|
-
return
|
|
812
|
+
return path6.join(this.globalBaseDir, ".running");
|
|
813
813
|
}
|
|
814
814
|
/**
|
|
815
815
|
* Get the docs directory path
|
|
816
816
|
* Contains documentation and help files
|
|
817
817
|
*/
|
|
818
818
|
getDocsPath() {
|
|
819
|
-
return
|
|
819
|
+
return path6.join(this.globalBaseDir, "docs");
|
|
820
820
|
}
|
|
821
821
|
/**
|
|
822
822
|
* Get the agents directory path for a project
|
|
@@ -824,23 +824,23 @@ var init_path_manager = __esm({
|
|
|
824
824
|
*/
|
|
825
825
|
getAgentsPath(projectId) {
|
|
826
826
|
if (projectId) {
|
|
827
|
-
return
|
|
827
|
+
return path6.join(this.getGlobalProjectPath(projectId), "agents");
|
|
828
828
|
}
|
|
829
|
-
return
|
|
829
|
+
return path6.join(this.globalBaseDir, "agents");
|
|
830
830
|
}
|
|
831
831
|
/**
|
|
832
832
|
* Get the storage file path for a project
|
|
833
833
|
* Convenience method for accessing storage layer files
|
|
834
834
|
*/
|
|
835
835
|
getStoragePath(projectId, filename) {
|
|
836
|
-
return
|
|
836
|
+
return path6.join(this.getGlobalProjectPath(projectId), "storage", filename);
|
|
837
837
|
}
|
|
838
838
|
/**
|
|
839
839
|
* Get the context directory path for a project
|
|
840
840
|
* Contains generated markdown context files
|
|
841
841
|
*/
|
|
842
842
|
getContextPath(projectId) {
|
|
843
|
-
return
|
|
843
|
+
return path6.join(this.getGlobalProjectPath(projectId), "context");
|
|
844
844
|
}
|
|
845
845
|
};
|
|
846
846
|
pathManager = new PathManager();
|
|
@@ -1130,18 +1130,18 @@ var init_errors = __esm({
|
|
|
1130
1130
|
});
|
|
1131
1131
|
|
|
1132
1132
|
// core/infrastructure/config-manager.ts
|
|
1133
|
-
import
|
|
1134
|
-
import
|
|
1135
|
-
import * as
|
|
1133
|
+
import fs7 from "fs/promises";
|
|
1134
|
+
import path7 from "path";
|
|
1135
|
+
import * as jsonc3 from "jsonc-parser";
|
|
1136
1136
|
function parseJsonc(content) {
|
|
1137
1137
|
const errors = [];
|
|
1138
|
-
const result =
|
|
1138
|
+
const result = jsonc3.parse(content, errors, {
|
|
1139
1139
|
allowTrailingComma: true,
|
|
1140
1140
|
disallowComments: false
|
|
1141
1141
|
});
|
|
1142
1142
|
if (errors.length > 0) {
|
|
1143
1143
|
const firstError = errors[0];
|
|
1144
|
-
throw new SyntaxError(`JSON parse error at offset ${firstError.offset}: ${
|
|
1144
|
+
throw new SyntaxError(`JSON parse error at offset ${firstError.offset}: ${jsonc3.printParseErrorCode(firstError.error)}`);
|
|
1145
1145
|
}
|
|
1146
1146
|
return result;
|
|
1147
1147
|
}
|
|
@@ -1160,9 +1160,6 @@ var init_config_manager = __esm({
|
|
|
1160
1160
|
static {
|
|
1161
1161
|
__name(this, "ConfigManager");
|
|
1162
1162
|
}
|
|
1163
|
-
// Cache projectId lookups with TTL (30 seconds) to avoid repeated disk reads
|
|
1164
|
-
projectIdCache = /* @__PURE__ */ new Map();
|
|
1165
|
-
CACHE_TTL = 3e4;
|
|
1166
1163
|
/**
|
|
1167
1164
|
* Read the project configuration file
|
|
1168
1165
|
* Supports both .json and .jsonc formats (with comments)
|
|
@@ -1170,7 +1167,7 @@ var init_config_manager = __esm({
|
|
|
1170
1167
|
async readConfig(projectPath) {
|
|
1171
1168
|
try {
|
|
1172
1169
|
const configPath = path_manager_default.getLocalConfigPath(projectPath);
|
|
1173
|
-
const content = await
|
|
1170
|
+
const content = await fs7.readFile(configPath, "utf-8");
|
|
1174
1171
|
return parseJsonc(content);
|
|
1175
1172
|
} catch (error) {
|
|
1176
1173
|
if (isNotFoundError(error)) {
|
|
@@ -1186,9 +1183,9 @@ var init_config_manager = __esm({
|
|
|
1186
1183
|
async writeConfig(projectPath, config) {
|
|
1187
1184
|
const configPath = path_manager_default.getLocalConfigPath(projectPath);
|
|
1188
1185
|
const configDir = path_manager_default.getLegacyPrjctPath(projectPath);
|
|
1189
|
-
await
|
|
1186
|
+
await fs7.mkdir(configDir, { recursive: true });
|
|
1190
1187
|
const content = JSON.stringify(config, null, 2);
|
|
1191
|
-
await
|
|
1188
|
+
await fs7.writeFile(configPath, content + "\n", "utf-8");
|
|
1192
1189
|
}
|
|
1193
1190
|
/**
|
|
1194
1191
|
* Read the global project configuration file
|
|
@@ -1198,7 +1195,7 @@ var init_config_manager = __esm({
|
|
|
1198
1195
|
async readGlobalConfig(projectId) {
|
|
1199
1196
|
try {
|
|
1200
1197
|
const configPath = path_manager_default.getGlobalProjectConfigPath(projectId);
|
|
1201
|
-
const content = await
|
|
1198
|
+
const content = await fs7.readFile(configPath, "utf-8");
|
|
1202
1199
|
return parseJsonc(content);
|
|
1203
1200
|
} catch (error) {
|
|
1204
1201
|
if (isNotFoundError(error)) {
|
|
@@ -1214,9 +1211,9 @@ var init_config_manager = __esm({
|
|
|
1214
1211
|
async writeGlobalConfig(projectId, config) {
|
|
1215
1212
|
const configPath = path_manager_default.getGlobalProjectConfigPath(projectId);
|
|
1216
1213
|
const configDir = path_manager_default.getGlobalProjectPath(projectId);
|
|
1217
|
-
await
|
|
1214
|
+
await fs7.mkdir(configDir, { recursive: true });
|
|
1218
1215
|
const content = JSON.stringify(config, null, 2);
|
|
1219
|
-
await
|
|
1216
|
+
await fs7.writeFile(configPath, content + "\n", "utf-8");
|
|
1220
1217
|
}
|
|
1221
1218
|
/**
|
|
1222
1219
|
* Ensure global config exists, create if not
|
|
@@ -1303,7 +1300,7 @@ var init_config_manager = __esm({
|
|
|
1303
1300
|
if (!config || !config.projectId) return true;
|
|
1304
1301
|
const globalPath = path_manager_default.getGlobalProjectPath(config.projectId);
|
|
1305
1302
|
try {
|
|
1306
|
-
const coreFiles = await
|
|
1303
|
+
const coreFiles = await fs7.readdir(path7.join(globalPath, "core"));
|
|
1307
1304
|
return coreFiles.length === 0;
|
|
1308
1305
|
} catch (error) {
|
|
1309
1306
|
if (isNotFoundError(error)) {
|
|
@@ -1314,23 +1311,13 @@ var init_config_manager = __esm({
|
|
|
1314
1311
|
}
|
|
1315
1312
|
/**
|
|
1316
1313
|
* Get the project ID from config, or generate it if config doesn't exist
|
|
1317
|
-
* Uses in-memory cache with TTL to avoid repeated disk reads
|
|
1318
1314
|
*/
|
|
1319
1315
|
async getProjectId(projectPath) {
|
|
1320
|
-
const cached = this.projectIdCache.get(projectPath);
|
|
1321
|
-
if (cached && Date.now() - cached.timestamp < this.CACHE_TTL) {
|
|
1322
|
-
return cached.id;
|
|
1323
|
-
}
|
|
1324
1316
|
const config = await this.readConfig(projectPath);
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
/**
|
|
1330
|
-
* Clear the projectId cache (useful for testing or after config changes)
|
|
1331
|
-
*/
|
|
1332
|
-
clearProjectIdCache() {
|
|
1333
|
-
this.projectIdCache.clear();
|
|
1317
|
+
if (config && config.projectId) {
|
|
1318
|
+
return config.projectId;
|
|
1319
|
+
}
|
|
1320
|
+
return path_manager_default.generateProjectId(projectPath);
|
|
1334
1321
|
}
|
|
1335
1322
|
/**
|
|
1336
1323
|
* Find an author in the authors array by github username
|
|
@@ -1416,21 +1403,21 @@ var init_config_manager = __esm({
|
|
|
1416
1403
|
});
|
|
1417
1404
|
|
|
1418
1405
|
// core/infrastructure/command-installer.ts
|
|
1419
|
-
import
|
|
1420
|
-
import
|
|
1421
|
-
import
|
|
1406
|
+
import fs8 from "fs/promises";
|
|
1407
|
+
import path8 from "path";
|
|
1408
|
+
import os4 from "os";
|
|
1422
1409
|
async function installDocs() {
|
|
1423
1410
|
try {
|
|
1424
|
-
const docsDir =
|
|
1425
|
-
const templateDocsDir =
|
|
1426
|
-
await
|
|
1427
|
-
const docFiles = await
|
|
1411
|
+
const docsDir = path8.join(os4.homedir(), ".prjct-cli", "docs");
|
|
1412
|
+
const templateDocsDir = path8.join(__dirname, "../../templates/global/docs");
|
|
1413
|
+
await fs8.mkdir(docsDir, { recursive: true });
|
|
1414
|
+
const docFiles = await fs8.readdir(templateDocsDir);
|
|
1428
1415
|
for (const file of docFiles) {
|
|
1429
1416
|
if (file.endsWith(".md")) {
|
|
1430
|
-
const srcPath =
|
|
1431
|
-
const destPath =
|
|
1432
|
-
const content = await
|
|
1433
|
-
await
|
|
1417
|
+
const srcPath = path8.join(templateDocsDir, file);
|
|
1418
|
+
const destPath = path8.join(docsDir, file);
|
|
1419
|
+
const content = await fs8.readFile(srcPath, "utf-8");
|
|
1420
|
+
await fs8.writeFile(destPath, content, "utf-8");
|
|
1434
1421
|
}
|
|
1435
1422
|
}
|
|
1436
1423
|
return { success: true };
|
|
@@ -1448,21 +1435,21 @@ async function installGlobalConfig(claudeConfigPath, detectClaude) {
|
|
|
1448
1435
|
};
|
|
1449
1436
|
}
|
|
1450
1437
|
try {
|
|
1451
|
-
const claudeDir =
|
|
1452
|
-
await
|
|
1453
|
-
const globalConfigPath =
|
|
1454
|
-
const templatePath =
|
|
1455
|
-
const templateContent = await
|
|
1438
|
+
const claudeDir = path8.join(os4.homedir(), ".claude");
|
|
1439
|
+
await fs8.mkdir(claudeDir, { recursive: true });
|
|
1440
|
+
const globalConfigPath = path8.join(claudeDir, "CLAUDE.md");
|
|
1441
|
+
const templatePath = path8.join(__dirname, "../../templates/global/CLAUDE.md");
|
|
1442
|
+
const templateContent = await fs8.readFile(templatePath, "utf-8");
|
|
1456
1443
|
let existingContent = "";
|
|
1457
1444
|
let fileExists2 = false;
|
|
1458
1445
|
try {
|
|
1459
|
-
existingContent = await
|
|
1446
|
+
existingContent = await fs8.readFile(globalConfigPath, "utf-8");
|
|
1460
1447
|
fileExists2 = true;
|
|
1461
1448
|
} catch {
|
|
1462
1449
|
fileExists2 = false;
|
|
1463
1450
|
}
|
|
1464
1451
|
if (!fileExists2) {
|
|
1465
|
-
await
|
|
1452
|
+
await fs8.writeFile(globalConfigPath, templateContent, "utf-8");
|
|
1466
1453
|
return {
|
|
1467
1454
|
success: true,
|
|
1468
1455
|
action: "created",
|
|
@@ -1474,7 +1461,7 @@ async function installGlobalConfig(claudeConfigPath, detectClaude) {
|
|
|
1474
1461
|
const hasMarkers = existingContent.includes(startMarker) && existingContent.includes(endMarker);
|
|
1475
1462
|
if (!hasMarkers) {
|
|
1476
1463
|
const updatedContent = existingContent + "\n\n" + templateContent;
|
|
1477
|
-
await
|
|
1464
|
+
await fs8.writeFile(globalConfigPath, updatedContent, "utf-8");
|
|
1478
1465
|
return {
|
|
1479
1466
|
success: true,
|
|
1480
1467
|
action: "appended",
|
|
@@ -1490,7 +1477,7 @@ async function installGlobalConfig(claudeConfigPath, detectClaude) {
|
|
|
1490
1477
|
templateContent.indexOf(endMarker) + endMarker.length
|
|
1491
1478
|
);
|
|
1492
1479
|
const updatedContent = beforeMarker + prjctSection + afterMarker;
|
|
1493
|
-
await
|
|
1480
|
+
await fs8.writeFile(globalConfigPath, updatedContent, "utf-8");
|
|
1494
1481
|
return {
|
|
1495
1482
|
success: true,
|
|
1496
1483
|
action: "updated",
|
|
@@ -1521,17 +1508,17 @@ var init_command_installer = __esm({
|
|
|
1521
1508
|
claudeConfigPath;
|
|
1522
1509
|
templatesDir;
|
|
1523
1510
|
constructor() {
|
|
1524
|
-
this.homeDir =
|
|
1525
|
-
this.claudeCommandsPath =
|
|
1526
|
-
this.claudeConfigPath =
|
|
1527
|
-
this.templatesDir =
|
|
1511
|
+
this.homeDir = os4.homedir();
|
|
1512
|
+
this.claudeCommandsPath = path8.join(this.homeDir, ".claude", "commands", "p");
|
|
1513
|
+
this.claudeConfigPath = path8.join(this.homeDir, ".claude");
|
|
1514
|
+
this.templatesDir = path8.join(__dirname, "..", "..", "templates", "commands");
|
|
1528
1515
|
}
|
|
1529
1516
|
/**
|
|
1530
1517
|
* Detect if Claude is installed
|
|
1531
1518
|
*/
|
|
1532
1519
|
async detectClaude() {
|
|
1533
1520
|
try {
|
|
1534
|
-
await
|
|
1521
|
+
await fs8.access(this.claudeConfigPath);
|
|
1535
1522
|
return true;
|
|
1536
1523
|
} catch {
|
|
1537
1524
|
return false;
|
|
@@ -1542,7 +1529,7 @@ var init_command_installer = __esm({
|
|
|
1542
1529
|
*/
|
|
1543
1530
|
async getCommandFiles() {
|
|
1544
1531
|
try {
|
|
1545
|
-
const files = await
|
|
1532
|
+
const files = await fs8.readdir(this.templatesDir);
|
|
1546
1533
|
return files.filter((f) => f.endsWith(".md"));
|
|
1547
1534
|
} catch {
|
|
1548
1535
|
return [
|
|
@@ -1581,16 +1568,16 @@ var init_command_installer = __esm({
|
|
|
1581
1568
|
}
|
|
1582
1569
|
try {
|
|
1583
1570
|
await this.installRouter();
|
|
1584
|
-
await
|
|
1571
|
+
await fs8.mkdir(this.claudeCommandsPath, { recursive: true });
|
|
1585
1572
|
const commandFiles = await this.getCommandFiles();
|
|
1586
1573
|
const installed = [];
|
|
1587
1574
|
const errors = [];
|
|
1588
1575
|
for (const file of commandFiles) {
|
|
1589
1576
|
try {
|
|
1590
|
-
const sourcePath =
|
|
1591
|
-
const destPath =
|
|
1592
|
-
const content = await
|
|
1593
|
-
await
|
|
1577
|
+
const sourcePath = path8.join(this.templatesDir, file);
|
|
1578
|
+
const destPath = path8.join(this.claudeCommandsPath, file);
|
|
1579
|
+
const content = await fs8.readFile(sourcePath, "utf-8");
|
|
1580
|
+
await fs8.writeFile(destPath, content, "utf-8");
|
|
1594
1581
|
installed.push(file.replace(".md", ""));
|
|
1595
1582
|
} catch (error) {
|
|
1596
1583
|
errors.push({ file, error: error.message });
|
|
@@ -1619,8 +1606,8 @@ var init_command_installer = __esm({
|
|
|
1619
1606
|
const errors = [];
|
|
1620
1607
|
for (const file of commandFiles) {
|
|
1621
1608
|
try {
|
|
1622
|
-
const filePath =
|
|
1623
|
-
await
|
|
1609
|
+
const filePath = path8.join(this.claudeCommandsPath, file);
|
|
1610
|
+
await fs8.unlink(filePath);
|
|
1624
1611
|
uninstalled.push(file.replace(".md", ""));
|
|
1625
1612
|
} catch (error) {
|
|
1626
1613
|
if (error.code !== "ENOENT") {
|
|
@@ -1629,7 +1616,7 @@ var init_command_installer = __esm({
|
|
|
1629
1616
|
}
|
|
1630
1617
|
}
|
|
1631
1618
|
try {
|
|
1632
|
-
await
|
|
1619
|
+
await fs8.rmdir(this.claudeCommandsPath);
|
|
1633
1620
|
} catch {
|
|
1634
1621
|
}
|
|
1635
1622
|
return {
|
|
@@ -1656,8 +1643,8 @@ var init_command_installer = __esm({
|
|
|
1656
1643
|
};
|
|
1657
1644
|
}
|
|
1658
1645
|
try {
|
|
1659
|
-
await
|
|
1660
|
-
const files = await
|
|
1646
|
+
await fs8.access(this.claudeCommandsPath);
|
|
1647
|
+
const files = await fs8.readdir(this.claudeCommandsPath);
|
|
1661
1648
|
const installedCommands = files.filter((f) => f.endsWith(".md")).map((f) => f.replace(".md", ""));
|
|
1662
1649
|
return {
|
|
1663
1650
|
installed: installedCommands.length > 0,
|
|
@@ -1701,8 +1688,8 @@ var init_command_installer = __esm({
|
|
|
1701
1688
|
*/
|
|
1702
1689
|
async verifyTemplate(commandName) {
|
|
1703
1690
|
try {
|
|
1704
|
-
const templatePath =
|
|
1705
|
-
await
|
|
1691
|
+
const templatePath = path8.join(this.templatesDir, `${commandName}.md`);
|
|
1692
|
+
await fs8.access(templatePath);
|
|
1706
1693
|
return true;
|
|
1707
1694
|
} catch {
|
|
1708
1695
|
return false;
|
|
@@ -1715,10 +1702,10 @@ var init_command_installer = __esm({
|
|
|
1715
1702
|
*/
|
|
1716
1703
|
async installRouter() {
|
|
1717
1704
|
try {
|
|
1718
|
-
const routerSource =
|
|
1719
|
-
const routerDest =
|
|
1720
|
-
const content = await
|
|
1721
|
-
await
|
|
1705
|
+
const routerSource = path8.join(this.templatesDir, "p.md");
|
|
1706
|
+
const routerDest = path8.join(this.homeDir, ".claude", "commands", "p.md");
|
|
1707
|
+
const content = await fs8.readFile(routerSource, "utf-8");
|
|
1708
|
+
await fs8.writeFile(routerDest, content, "utf-8");
|
|
1722
1709
|
return true;
|
|
1723
1710
|
} catch {
|
|
1724
1711
|
return false;
|
|
@@ -1740,11 +1727,11 @@ var init_command_installer = __esm({
|
|
|
1740
1727
|
}
|
|
1741
1728
|
try {
|
|
1742
1729
|
await this.installRouter();
|
|
1743
|
-
await
|
|
1730
|
+
await fs8.mkdir(this.claudeCommandsPath, { recursive: true });
|
|
1744
1731
|
const templateFiles = await this.getCommandFiles();
|
|
1745
1732
|
let installedFiles = [];
|
|
1746
1733
|
try {
|
|
1747
|
-
installedFiles = await
|
|
1734
|
+
installedFiles = await fs8.readdir(this.claudeCommandsPath);
|
|
1748
1735
|
installedFiles = installedFiles.filter((f) => f.endsWith(".md"));
|
|
1749
1736
|
} catch {
|
|
1750
1737
|
installedFiles = [];
|
|
@@ -1758,11 +1745,11 @@ var init_command_installer = __esm({
|
|
|
1758
1745
|
};
|
|
1759
1746
|
for (const file of templateFiles) {
|
|
1760
1747
|
try {
|
|
1761
|
-
const sourcePath =
|
|
1762
|
-
const destPath =
|
|
1748
|
+
const sourcePath = path8.join(this.templatesDir, file);
|
|
1749
|
+
const destPath = path8.join(this.claudeCommandsPath, file);
|
|
1763
1750
|
const exists = installedFiles.includes(file);
|
|
1764
|
-
const content = await
|
|
1765
|
-
await
|
|
1751
|
+
const content = await fs8.readFile(sourcePath, "utf-8");
|
|
1752
|
+
await fs8.writeFile(destPath, content, "utf-8");
|
|
1766
1753
|
if (!exists) {
|
|
1767
1754
|
results.added++;
|
|
1768
1755
|
} else {
|
|
@@ -1808,9 +1795,9 @@ __export(setup_exports, {
|
|
|
1808
1795
|
run: () => run
|
|
1809
1796
|
});
|
|
1810
1797
|
import { execSync } from "child_process";
|
|
1811
|
-
import
|
|
1812
|
-
import
|
|
1813
|
-
import
|
|
1798
|
+
import fs9 from "fs";
|
|
1799
|
+
import path9 from "path";
|
|
1800
|
+
import os5 from "os";
|
|
1814
1801
|
async function hasClaudeCodeCLI() {
|
|
1815
1802
|
try {
|
|
1816
1803
|
execSync("which claude", { stdio: "ignore" });
|
|
@@ -1872,23 +1859,23 @@ async function run() {
|
|
|
1872
1859
|
}
|
|
1873
1860
|
async function migrateProjectsCliVersion() {
|
|
1874
1861
|
try {
|
|
1875
|
-
const projectsDir =
|
|
1876
|
-
if (!
|
|
1862
|
+
const projectsDir = path9.join(os5.homedir(), ".prjct-cli", "projects");
|
|
1863
|
+
if (!fs9.existsSync(projectsDir)) {
|
|
1877
1864
|
return;
|
|
1878
1865
|
}
|
|
1879
|
-
const projectDirs =
|
|
1866
|
+
const projectDirs = fs9.readdirSync(projectsDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
|
|
1880
1867
|
let migrated = 0;
|
|
1881
1868
|
for (const projectId of projectDirs) {
|
|
1882
|
-
const projectJsonPath =
|
|
1883
|
-
if (!
|
|
1869
|
+
const projectJsonPath = path9.join(projectsDir, projectId, "project.json");
|
|
1870
|
+
if (!fs9.existsSync(projectJsonPath)) {
|
|
1884
1871
|
continue;
|
|
1885
1872
|
}
|
|
1886
1873
|
try {
|
|
1887
|
-
const content =
|
|
1874
|
+
const content = fs9.readFileSync(projectJsonPath, "utf8");
|
|
1888
1875
|
const project = JSON.parse(content);
|
|
1889
1876
|
if (project.cliVersion !== VERSION) {
|
|
1890
1877
|
project.cliVersion = VERSION;
|
|
1891
|
-
|
|
1878
|
+
fs9.writeFileSync(projectJsonPath, JSON.stringify(project, null, 2));
|
|
1892
1879
|
migrated++;
|
|
1893
1880
|
}
|
|
1894
1881
|
} catch {
|
|
@@ -1900,85 +1887,162 @@ async function migrateProjectsCliVersion() {
|
|
|
1900
1887
|
} catch {
|
|
1901
1888
|
}
|
|
1902
1889
|
}
|
|
1890
|
+
function ensureStatusLineSettings(settingsPath, statusLinePath) {
|
|
1891
|
+
let settings = {};
|
|
1892
|
+
if (fs9.existsSync(settingsPath)) {
|
|
1893
|
+
try {
|
|
1894
|
+
settings = JSON.parse(fs9.readFileSync(settingsPath, "utf8"));
|
|
1895
|
+
} catch {
|
|
1896
|
+
}
|
|
1897
|
+
}
|
|
1898
|
+
settings.statusLine = { type: "command", command: statusLinePath };
|
|
1899
|
+
fs9.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
1900
|
+
}
|
|
1903
1901
|
async function installStatusLine() {
|
|
1904
1902
|
try {
|
|
1905
|
-
const claudeDir =
|
|
1906
|
-
const settingsPath =
|
|
1907
|
-
const
|
|
1908
|
-
|
|
1909
|
-
|
|
1903
|
+
const claudeDir = path9.join(os5.homedir(), ".claude");
|
|
1904
|
+
const settingsPath = path9.join(claudeDir, "settings.json");
|
|
1905
|
+
const claudeStatusLinePath = path9.join(claudeDir, "prjct-statusline.sh");
|
|
1906
|
+
const prjctStatusLineDir = path9.join(os5.homedir(), ".prjct-cli", "statusline");
|
|
1907
|
+
const prjctStatusLinePath = path9.join(prjctStatusLineDir, "statusline.sh");
|
|
1908
|
+
const prjctThemesDir = path9.join(prjctStatusLineDir, "themes");
|
|
1909
|
+
const prjctLibDir = path9.join(prjctStatusLineDir, "lib");
|
|
1910
|
+
const prjctComponentsDir = path9.join(prjctStatusLineDir, "components");
|
|
1911
|
+
const prjctConfigPath = path9.join(prjctStatusLineDir, "config.json");
|
|
1912
|
+
const assetsDir = path9.join(__dirname, "..", "..", "assets", "statusline");
|
|
1913
|
+
const sourceScript = path9.join(assetsDir, "statusline.sh");
|
|
1914
|
+
const sourceThemeDir = path9.join(assetsDir, "themes");
|
|
1915
|
+
const sourceLibDir = path9.join(assetsDir, "lib");
|
|
1916
|
+
const sourceComponentsDir = path9.join(assetsDir, "components");
|
|
1917
|
+
const sourceConfigPath = path9.join(assetsDir, "default-config.json");
|
|
1918
|
+
if (!fs9.existsSync(claudeDir)) {
|
|
1919
|
+
fs9.mkdirSync(claudeDir, { recursive: true });
|
|
1920
|
+
}
|
|
1921
|
+
if (!fs9.existsSync(prjctStatusLineDir)) {
|
|
1922
|
+
fs9.mkdirSync(prjctStatusLineDir, { recursive: true });
|
|
1923
|
+
}
|
|
1924
|
+
if (!fs9.existsSync(prjctThemesDir)) {
|
|
1925
|
+
fs9.mkdirSync(prjctThemesDir, { recursive: true });
|
|
1926
|
+
}
|
|
1927
|
+
if (!fs9.existsSync(prjctLibDir)) {
|
|
1928
|
+
fs9.mkdirSync(prjctLibDir, { recursive: true });
|
|
1910
1929
|
}
|
|
1911
|
-
|
|
1930
|
+
if (!fs9.existsSync(prjctComponentsDir)) {
|
|
1931
|
+
fs9.mkdirSync(prjctComponentsDir, { recursive: true });
|
|
1932
|
+
}
|
|
1933
|
+
if (fs9.existsSync(prjctStatusLinePath)) {
|
|
1934
|
+
const existingContent = fs9.readFileSync(prjctStatusLinePath, "utf8");
|
|
1935
|
+
if (existingContent.includes("CLI_VERSION=")) {
|
|
1936
|
+
const versionMatch = existingContent.match(/CLI_VERSION="([^"]*)"/);
|
|
1937
|
+
if (versionMatch && versionMatch[1] !== VERSION) {
|
|
1938
|
+
const updatedContent = existingContent.replace(
|
|
1939
|
+
/CLI_VERSION="[^"]*"/,
|
|
1940
|
+
`CLI_VERSION="${VERSION}"`
|
|
1941
|
+
);
|
|
1942
|
+
fs9.writeFileSync(prjctStatusLinePath, updatedContent, { mode: 493 });
|
|
1943
|
+
}
|
|
1944
|
+
installStatusLineModules(sourceLibDir, prjctLibDir);
|
|
1945
|
+
installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
|
|
1946
|
+
ensureStatusLineSymlink(claudeStatusLinePath, prjctStatusLinePath);
|
|
1947
|
+
ensureStatusLineSettings(settingsPath, claudeStatusLinePath);
|
|
1948
|
+
return;
|
|
1949
|
+
}
|
|
1950
|
+
}
|
|
1951
|
+
if (fs9.existsSync(sourceScript)) {
|
|
1952
|
+
let scriptContent = fs9.readFileSync(sourceScript, "utf8");
|
|
1953
|
+
scriptContent = scriptContent.replace(
|
|
1954
|
+
/CLI_VERSION="[^"]*"/,
|
|
1955
|
+
`CLI_VERSION="${VERSION}"`
|
|
1956
|
+
);
|
|
1957
|
+
fs9.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
|
|
1958
|
+
installStatusLineModules(sourceLibDir, prjctLibDir);
|
|
1959
|
+
installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
|
|
1960
|
+
if (fs9.existsSync(sourceThemeDir)) {
|
|
1961
|
+
const themes = fs9.readdirSync(sourceThemeDir);
|
|
1962
|
+
for (const theme of themes) {
|
|
1963
|
+
const src = path9.join(sourceThemeDir, theme);
|
|
1964
|
+
const dest = path9.join(prjctThemesDir, theme);
|
|
1965
|
+
fs9.copyFileSync(src, dest);
|
|
1966
|
+
}
|
|
1967
|
+
}
|
|
1968
|
+
if (!fs9.existsSync(prjctConfigPath) && fs9.existsSync(sourceConfigPath)) {
|
|
1969
|
+
fs9.copyFileSync(sourceConfigPath, prjctConfigPath);
|
|
1970
|
+
}
|
|
1971
|
+
} else {
|
|
1972
|
+
const scriptContent = `#!/bin/bash
|
|
1912
1973
|
# prjct Status Line for Claude Code
|
|
1913
|
-
# Shows version update notifications and current task
|
|
1914
|
-
|
|
1915
|
-
# Current CLI version (embedded at install time)
|
|
1916
1974
|
CLI_VERSION="${VERSION}"
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
read -r json
|
|
1920
|
-
|
|
1921
|
-
# Extract cwd from JSON
|
|
1922
|
-
CWD=$(echo "$json" | grep -o '"cwd"[[:space:]]*:[[:space:]]*"[^"]*"' | sed 's/.*"cwd"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/')
|
|
1923
|
-
|
|
1924
|
-
# Check if this is a prjct project
|
|
1975
|
+
input=$(cat)
|
|
1976
|
+
CWD=$(echo "$input" | jq -r '.workspace.current_dir // "~"' 2>/dev/null)
|
|
1925
1977
|
CONFIG="$CWD/.prjct/prjct.config.json"
|
|
1926
|
-
if [
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
if [[ -n "$PROJECT_ID" ]]; then
|
|
1978
|
+
if [ -f "$CONFIG" ]; then
|
|
1979
|
+
PROJECT_ID=$(jq -r '.projectId // ""' "$CONFIG" 2>/dev/null)
|
|
1980
|
+
if [ -n "$PROJECT_ID" ]; then
|
|
1931
1981
|
PROJECT_JSON="$HOME/.prjct-cli/projects/$PROJECT_ID/project.json"
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
# If no cliVersion or different version, show update notice
|
|
1938
|
-
if [[ -z "$PROJECT_VERSION" ]] || [[ "$PROJECT_VERSION" != "$CLI_VERSION" ]]; then
|
|
1939
|
-
echo "\u26A0\uFE0F prjct v$CLI_VERSION available! Run /p:sync"
|
|
1982
|
+
if [ -f "$PROJECT_JSON" ]; then
|
|
1983
|
+
PROJECT_VERSION=$(jq -r '.cliVersion // ""' "$PROJECT_JSON" 2>/dev/null)
|
|
1984
|
+
if [ -z "$PROJECT_VERSION" ] || [ "$PROJECT_VERSION" != "$CLI_VERSION" ]; then
|
|
1985
|
+
echo "prjct v$CLI_VERSION - run p. sync"
|
|
1940
1986
|
exit 0
|
|
1941
1987
|
fi
|
|
1942
1988
|
else
|
|
1943
|
-
|
|
1944
|
-
echo "\u26A0\uFE0F prjct v$CLI_VERSION available! Run /p:sync"
|
|
1989
|
+
echo "prjct v$CLI_VERSION - run p. sync"
|
|
1945
1990
|
exit 0
|
|
1946
1991
|
fi
|
|
1947
|
-
|
|
1948
|
-
# Show current task if exists
|
|
1949
1992
|
STATE="$HOME/.prjct-cli/projects/$PROJECT_ID/storage/state.json"
|
|
1950
|
-
if [
|
|
1951
|
-
TASK=$(
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
if [[ -n "$TASK" ]] && [[ "$STATUS" == "active" ]]; then
|
|
1955
|
-
# Truncate task to 40 chars
|
|
1956
|
-
TASK_SHORT="\${TASK:0:40}"
|
|
1957
|
-
[[ \${#TASK} -gt 40 ]] && TASK_SHORT="$TASK_SHORT..."
|
|
1958
|
-
echo "\u{1F3AF} $TASK_SHORT"
|
|
1993
|
+
if [ -f "$STATE" ]; then
|
|
1994
|
+
TASK=$(jq -r '.currentTask.description // ""' "$STATE" 2>/dev/null)
|
|
1995
|
+
if [ -n "$TASK" ]; then
|
|
1996
|
+
echo "$TASK"
|
|
1959
1997
|
exit 0
|
|
1960
1998
|
fi
|
|
1961
1999
|
fi
|
|
1962
2000
|
fi
|
|
1963
2001
|
fi
|
|
1964
|
-
|
|
1965
|
-
# Default: show prjct branding
|
|
1966
|
-
echo "\u26A1 prjct"
|
|
2002
|
+
echo "prjct"
|
|
1967
2003
|
`;
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
2004
|
+
fs9.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
|
|
2005
|
+
}
|
|
2006
|
+
ensureStatusLineSymlink(claudeStatusLinePath, prjctStatusLinePath);
|
|
2007
|
+
ensureStatusLineSettings(settingsPath, claudeStatusLinePath);
|
|
2008
|
+
} catch {
|
|
2009
|
+
}
|
|
2010
|
+
}
|
|
2011
|
+
function installStatusLineModules(sourceDir, destDir) {
|
|
2012
|
+
if (!fs9.existsSync(sourceDir)) {
|
|
2013
|
+
return;
|
|
2014
|
+
}
|
|
2015
|
+
const files = fs9.readdirSync(sourceDir);
|
|
2016
|
+
for (const file of files) {
|
|
2017
|
+
if (file.endsWith(".sh")) {
|
|
2018
|
+
const src = path9.join(sourceDir, file);
|
|
2019
|
+
const dest = path9.join(destDir, file);
|
|
2020
|
+
fs9.copyFileSync(src, dest);
|
|
2021
|
+
fs9.chmodSync(dest, 493);
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
function ensureStatusLineSymlink(linkPath, targetPath) {
|
|
2026
|
+
try {
|
|
2027
|
+
if (fs9.existsSync(linkPath)) {
|
|
2028
|
+
const stats = fs9.lstatSync(linkPath);
|
|
2029
|
+
if (stats.isSymbolicLink()) {
|
|
2030
|
+
const existingTarget = fs9.readlinkSync(linkPath);
|
|
2031
|
+
if (existingTarget === targetPath) {
|
|
2032
|
+
return;
|
|
2033
|
+
}
|
|
1974
2034
|
}
|
|
2035
|
+
fs9.unlinkSync(linkPath);
|
|
1975
2036
|
}
|
|
1976
|
-
|
|
1977
|
-
type: "command",
|
|
1978
|
-
command: statusLinePath
|
|
1979
|
-
};
|
|
1980
|
-
fs8.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
2037
|
+
fs9.symlinkSync(targetPath, linkPath);
|
|
1981
2038
|
} catch {
|
|
2039
|
+
try {
|
|
2040
|
+
if (fs9.existsSync(targetPath)) {
|
|
2041
|
+
fs9.copyFileSync(targetPath, linkPath);
|
|
2042
|
+
fs9.chmodSync(linkPath, 493);
|
|
2043
|
+
}
|
|
2044
|
+
} catch {
|
|
2045
|
+
}
|
|
1982
2046
|
}
|
|
1983
2047
|
}
|
|
1984
2048
|
function showResults(results) {
|
|
@@ -2022,7 +2086,10 @@ var init_setup = __esm({
|
|
|
2022
2086
|
__name(run, "run");
|
|
2023
2087
|
setup_default = { run };
|
|
2024
2088
|
__name(migrateProjectsCliVersion, "migrateProjectsCliVersion");
|
|
2089
|
+
__name(ensureStatusLineSettings, "ensureStatusLineSettings");
|
|
2025
2090
|
__name(installStatusLine, "installStatusLine");
|
|
2091
|
+
__name(installStatusLineModules, "installStatusLineModules");
|
|
2092
|
+
__name(ensureStatusLineSymlink, "ensureStatusLineSymlink");
|
|
2026
2093
|
__name(showResults, "showResults");
|
|
2027
2094
|
}
|
|
2028
2095
|
});
|
|
@@ -2236,7 +2303,7 @@ var init_ideas = __esm({
|
|
|
2236
2303
|
|
|
2237
2304
|
// core/schemas/roadmap.ts
|
|
2238
2305
|
import { z as z5 } from "zod";
|
|
2239
|
-
var FeatureStatusSchema, FeatureImpactSchema, FeatureTypeSchema, PhaseStatusSchema, FeatureTaskSchema, RoadmapPhaseSchema, RoadmapStrategySchema, FeatureDurationSchema, FeatureItemSchema, RoadmapJsonSchema, DEFAULT_FEATURE;
|
|
2306
|
+
var FeatureStatusSchema, FeatureImpactSchema, FeatureTypeSchema, PhaseStatusSchema, QuarterStatusSchema, InferredFromSchema, FeatureTaskSchema, RoadmapPhaseSchema, RoadmapStrategySchema, FeatureDurationSchema, GitCommitSchema, EffortEstimateSchema, EffortActualSchema, FeatureEffortSchema, QuarterCapacitySchema, QuarterSchema, FeatureItemSchema, BacklogItemSchema, RoadmapJsonSchema, DEFAULT_FEATURE;
|
|
2240
2307
|
var init_roadmap = __esm({
|
|
2241
2308
|
"core/schemas/roadmap.ts"() {
|
|
2242
2309
|
"use strict";
|
|
@@ -2244,6 +2311,8 @@ var init_roadmap = __esm({
|
|
|
2244
2311
|
FeatureImpactSchema = z5.enum(["low", "medium", "high"]);
|
|
2245
2312
|
FeatureTypeSchema = z5.enum(["feature", "breaking_change", "refactor", "infrastructure"]);
|
|
2246
2313
|
PhaseStatusSchema = z5.enum(["completed", "active", "planned"]);
|
|
2314
|
+
QuarterStatusSchema = z5.enum(["planned", "active", "completed"]);
|
|
2315
|
+
InferredFromSchema = z5.enum(["git", "git-branch", "manual", "prd"]);
|
|
2247
2316
|
FeatureTaskSchema = z5.object({
|
|
2248
2317
|
id: z5.string(),
|
|
2249
2318
|
// task_xxxxxxxx
|
|
@@ -2269,6 +2338,53 @@ var init_roadmap = __esm({
|
|
|
2269
2338
|
totalMinutes: z5.number(),
|
|
2270
2339
|
display: z5.string().optional()
|
|
2271
2340
|
});
|
|
2341
|
+
GitCommitSchema = z5.object({
|
|
2342
|
+
hash: z5.string(),
|
|
2343
|
+
message: z5.string(),
|
|
2344
|
+
date: z5.string(),
|
|
2345
|
+
author: z5.string().optional()
|
|
2346
|
+
});
|
|
2347
|
+
EffortEstimateSchema = z5.object({
|
|
2348
|
+
hours: z5.number(),
|
|
2349
|
+
confidence: z5.enum(["low", "medium", "high"]).optional(),
|
|
2350
|
+
breakdown: z5.array(z5.object({
|
|
2351
|
+
area: z5.string(),
|
|
2352
|
+
hours: z5.number()
|
|
2353
|
+
})).optional()
|
|
2354
|
+
});
|
|
2355
|
+
EffortActualSchema = z5.object({
|
|
2356
|
+
hours: z5.number().optional(),
|
|
2357
|
+
commits: z5.number().optional(),
|
|
2358
|
+
linesAdded: z5.number().optional(),
|
|
2359
|
+
linesRemoved: z5.number().optional()
|
|
2360
|
+
});
|
|
2361
|
+
FeatureEffortSchema = z5.object({
|
|
2362
|
+
estimated: EffortEstimateSchema.nullable(),
|
|
2363
|
+
actual: EffortActualSchema.nullable()
|
|
2364
|
+
});
|
|
2365
|
+
QuarterCapacitySchema = z5.object({
|
|
2366
|
+
totalHours: z5.number(),
|
|
2367
|
+
allocatedHours: z5.number(),
|
|
2368
|
+
bufferPercent: z5.number().optional()
|
|
2369
|
+
// % reserved for unknowns
|
|
2370
|
+
});
|
|
2371
|
+
QuarterSchema = z5.object({
|
|
2372
|
+
id: z5.string(),
|
|
2373
|
+
// Q1-2026
|
|
2374
|
+
name: z5.string(),
|
|
2375
|
+
// "Q1 2026"
|
|
2376
|
+
theme: z5.string().optional(),
|
|
2377
|
+
// "Foundation"
|
|
2378
|
+
goals: z5.array(z5.string()).optional(),
|
|
2379
|
+
features: z5.array(z5.string()),
|
|
2380
|
+
// Feature IDs
|
|
2381
|
+
capacity: QuarterCapacitySchema.optional(),
|
|
2382
|
+
status: QuarterStatusSchema,
|
|
2383
|
+
startDate: z5.string().optional(),
|
|
2384
|
+
// ISO8601
|
|
2385
|
+
endDate: z5.string().optional()
|
|
2386
|
+
// ISO8601
|
|
2387
|
+
});
|
|
2272
2388
|
FeatureItemSchema = z5.object({
|
|
2273
2389
|
id: z5.string(),
|
|
2274
2390
|
// feat_xxxxxxxx
|
|
@@ -2301,13 +2417,59 @@ var init_roadmap = __esm({
|
|
|
2301
2417
|
agent: z5.string().optional(),
|
|
2302
2418
|
// "fe+be", "fe", "be"
|
|
2303
2419
|
sprintName: z5.string().optional(),
|
|
2304
|
-
completedDate: z5.string().optional()
|
|
2420
|
+
completedDate: z5.string().optional(),
|
|
2421
|
+
// =========================================================================
|
|
2422
|
+
// AI ORCHESTRATION FIELDS (v0.29.0)
|
|
2423
|
+
// =========================================================================
|
|
2424
|
+
// PRD Integration
|
|
2425
|
+
prdId: z5.string().nullable().optional(),
|
|
2426
|
+
// Link to PRD (prd_xxxxxxxx)
|
|
2427
|
+
// Legacy Support (for existing projects)
|
|
2428
|
+
legacy: z5.boolean().optional(),
|
|
2429
|
+
// true = no PRD required
|
|
2430
|
+
inferredFrom: InferredFromSchema.optional(),
|
|
2431
|
+
// git, git-branch, manual, prd
|
|
2432
|
+
// Quarter Planning
|
|
2433
|
+
quarter: z5.string().nullable().optional(),
|
|
2434
|
+
// Q1-2026, etc.
|
|
2435
|
+
// Dependency Tracking
|
|
2436
|
+
dependencies: z5.array(z5.string()).optional(),
|
|
2437
|
+
// Feature IDs this depends on
|
|
2438
|
+
blockedBy: z5.array(z5.string()).optional(),
|
|
2439
|
+
// Feature IDs blocking this
|
|
2440
|
+
// Effort Tracking (for PRD comparison)
|
|
2441
|
+
effortTracking: FeatureEffortSchema.optional(),
|
|
2442
|
+
// Value Scoring (calculated from PRD)
|
|
2443
|
+
valueScore: z5.number().optional(),
|
|
2444
|
+
// Calculated priority score
|
|
2445
|
+
// Git Data (for legacy features)
|
|
2446
|
+
commits: z5.array(GitCommitSchema).optional(),
|
|
2447
|
+
// Commits for this feature
|
|
2448
|
+
branch: z5.string().optional(),
|
|
2449
|
+
// Branch name (for active)
|
|
2450
|
+
commitsAhead: z5.number().optional()
|
|
2451
|
+
// Commits ahead of main
|
|
2452
|
+
});
|
|
2453
|
+
BacklogItemSchema = z5.object({
|
|
2454
|
+
id: z5.string(),
|
|
2455
|
+
title: z5.string(),
|
|
2456
|
+
prdId: z5.string().nullable().optional(),
|
|
2457
|
+
valueScore: z5.number().optional(),
|
|
2458
|
+
effortEstimate: z5.number().optional(),
|
|
2459
|
+
reason: z5.string().optional()
|
|
2460
|
+
// Why in backlog
|
|
2305
2461
|
});
|
|
2306
2462
|
RoadmapJsonSchema = z5.object({
|
|
2307
2463
|
strategy: RoadmapStrategySchema.nullable().optional(),
|
|
2308
2464
|
features: z5.array(FeatureItemSchema),
|
|
2309
|
-
backlog: z5.array(z5.string()),
|
|
2310
|
-
|
|
2465
|
+
backlog: z5.array(z5.union([z5.string(), BacklogItemSchema])),
|
|
2466
|
+
// Support both formats
|
|
2467
|
+
lastUpdated: z5.string(),
|
|
2468
|
+
// AI ORCHESTRATION FIELDS (v0.29.0)
|
|
2469
|
+
quarters: z5.array(QuarterSchema).optional(),
|
|
2470
|
+
// Metadata (for git-inferred roadmaps)
|
|
2471
|
+
generatedFrom: z5.enum(["git-history", "manual", "prd"]).optional(),
|
|
2472
|
+
generatedAt: z5.string().optional()
|
|
2311
2473
|
});
|
|
2312
2474
|
DEFAULT_FEATURE = {
|
|
2313
2475
|
date: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
|
|
@@ -2315,7 +2477,11 @@ var init_roadmap = __esm({
|
|
|
2315
2477
|
impact: "medium",
|
|
2316
2478
|
progress: 0,
|
|
2317
2479
|
tasks: [],
|
|
2318
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2480
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2481
|
+
// AI Orchestration defaults
|
|
2482
|
+
prdId: null,
|
|
2483
|
+
legacy: false,
|
|
2484
|
+
quarter: null
|
|
2319
2485
|
};
|
|
2320
2486
|
}
|
|
2321
2487
|
});
|
|
@@ -2401,14 +2567,200 @@ var init_analysis = __esm({
|
|
|
2401
2567
|
});
|
|
2402
2568
|
|
|
2403
2569
|
// core/schemas/outcomes.ts
|
|
2570
|
+
import { z as z7 } from "zod";
|
|
2571
|
+
var QualityScoreSchema, SuccessLevelSchema, WorthAssessmentSchema, VarianceReasonSchema, EffortComparisonSchema, MetricResultSchema, AcceptanceCriteriaResultSchema, SuccessTrackingSchema, LearningSchema, LearningsSchema, ROIAssessmentSchema, TaskOutcomeSchema, FeatureOutcomeSchema, AggregateMetricsSchema, OutcomesJsonSchema;
|
|
2404
2572
|
var init_outcomes = __esm({
|
|
2405
2573
|
"core/schemas/outcomes.ts"() {
|
|
2406
2574
|
"use strict";
|
|
2575
|
+
QualityScoreSchema = z7.number().min(1).max(5);
|
|
2576
|
+
SuccessLevelSchema = z7.enum(["exceeded", "met", "partial", "failed"]);
|
|
2577
|
+
WorthAssessmentSchema = z7.enum(["definitely", "probably", "maybe", "no"]);
|
|
2578
|
+
VarianceReasonSchema = z7.enum([
|
|
2579
|
+
"scope_creep",
|
|
2580
|
+
"underestimated_complexity",
|
|
2581
|
+
"technical_debt",
|
|
2582
|
+
"external_blockers",
|
|
2583
|
+
"learning_curve",
|
|
2584
|
+
"requirements_changed",
|
|
2585
|
+
"optimistic_estimate",
|
|
2586
|
+
"team_changes",
|
|
2587
|
+
"other"
|
|
2588
|
+
]);
|
|
2589
|
+
EffortComparisonSchema = z7.object({
|
|
2590
|
+
estimated: z7.object({
|
|
2591
|
+
hours: z7.number(),
|
|
2592
|
+
confidence: z7.enum(["low", "medium", "high"]).optional(),
|
|
2593
|
+
source: z7.enum(["prd", "manual", "historical"]).optional()
|
|
2594
|
+
}),
|
|
2595
|
+
actual: z7.object({
|
|
2596
|
+
hours: z7.number(),
|
|
2597
|
+
commits: z7.number().optional(),
|
|
2598
|
+
linesAdded: z7.number().optional(),
|
|
2599
|
+
linesRemoved: z7.number().optional(),
|
|
2600
|
+
sessions: z7.number().optional()
|
|
2601
|
+
// Number of work sessions
|
|
2602
|
+
}),
|
|
2603
|
+
variance: z7.object({
|
|
2604
|
+
hours: z7.number(),
|
|
2605
|
+
// actual - estimated
|
|
2606
|
+
percentage: z7.number(),
|
|
2607
|
+
// ((actual - estimated) / estimated) * 100
|
|
2608
|
+
reason: VarianceReasonSchema.optional(),
|
|
2609
|
+
explanation: z7.string().optional()
|
|
2610
|
+
})
|
|
2611
|
+
});
|
|
2612
|
+
MetricResultSchema = z7.object({
|
|
2613
|
+
name: z7.string(),
|
|
2614
|
+
baseline: z7.number().nullable(),
|
|
2615
|
+
target: z7.number(),
|
|
2616
|
+
actual: z7.number(),
|
|
2617
|
+
unit: z7.string(),
|
|
2618
|
+
achieved: z7.boolean(),
|
|
2619
|
+
// actual >= target (or <= for decrease metrics)
|
|
2620
|
+
percentOfTarget: z7.number()
|
|
2621
|
+
// (actual / target) * 100
|
|
2622
|
+
});
|
|
2623
|
+
AcceptanceCriteriaResultSchema = z7.object({
|
|
2624
|
+
criteria: z7.string(),
|
|
2625
|
+
met: z7.boolean(),
|
|
2626
|
+
notes: z7.string().optional()
|
|
2627
|
+
});
|
|
2628
|
+
SuccessTrackingSchema = z7.object({
|
|
2629
|
+
metrics: z7.array(MetricResultSchema),
|
|
2630
|
+
acceptanceCriteria: z7.array(AcceptanceCriteriaResultSchema),
|
|
2631
|
+
overallSuccess: SuccessLevelSchema,
|
|
2632
|
+
successScore: z7.number().min(0).max(100)
|
|
2633
|
+
// Percentage of metrics/criteria met
|
|
2634
|
+
});
|
|
2635
|
+
LearningSchema = z7.object({
|
|
2636
|
+
category: z7.enum([
|
|
2637
|
+
"estimation",
|
|
2638
|
+
"technical",
|
|
2639
|
+
"process",
|
|
2640
|
+
"communication",
|
|
2641
|
+
"tooling",
|
|
2642
|
+
"architecture",
|
|
2643
|
+
"testing",
|
|
2644
|
+
"other"
|
|
2645
|
+
]),
|
|
2646
|
+
insight: z7.string(),
|
|
2647
|
+
actionable: z7.boolean(),
|
|
2648
|
+
action: z7.string().optional()
|
|
2649
|
+
// What to do differently next time
|
|
2650
|
+
});
|
|
2651
|
+
LearningsSchema = z7.object({
|
|
2652
|
+
whatWorked: z7.array(z7.string()),
|
|
2653
|
+
whatDidnt: z7.array(z7.string()),
|
|
2654
|
+
surprises: z7.array(z7.string()),
|
|
2655
|
+
recommendations: z7.array(LearningSchema)
|
|
2656
|
+
});
|
|
2657
|
+
ROIAssessmentSchema = z7.object({
|
|
2658
|
+
valueDelivered: z7.number().min(1).max(10),
|
|
2659
|
+
// Subjective 1-10 score
|
|
2660
|
+
userImpact: z7.enum(["none", "low", "medium", "high", "critical"]),
|
|
2661
|
+
businessImpact: z7.enum(["none", "low", "medium", "high", "critical"]),
|
|
2662
|
+
// Calculated: (valueDelivered * 10) / (actual hours)
|
|
2663
|
+
roiScore: z7.number(),
|
|
2664
|
+
// Would you build this again knowing what you know now?
|
|
2665
|
+
worthIt: WorthAssessmentSchema,
|
|
2666
|
+
worthItReason: z7.string().optional(),
|
|
2667
|
+
// Comparison to alternatives
|
|
2668
|
+
alternativeConsidered: z7.string().optional(),
|
|
2669
|
+
betterAlternativeExists: z7.boolean().optional()
|
|
2670
|
+
});
|
|
2671
|
+
TaskOutcomeSchema = z7.object({
|
|
2672
|
+
id: z7.string(),
|
|
2673
|
+
// out_task_xxxxxxxx
|
|
2674
|
+
taskId: z7.string(),
|
|
2675
|
+
description: z7.string(),
|
|
2676
|
+
// Time tracking
|
|
2677
|
+
estimatedMinutes: z7.number().optional(),
|
|
2678
|
+
actualMinutes: z7.number(),
|
|
2679
|
+
// Quality
|
|
2680
|
+
completedAsPlanned: z7.boolean(),
|
|
2681
|
+
qualityScore: QualityScoreSchema,
|
|
2682
|
+
// Context
|
|
2683
|
+
blockers: z7.array(z7.string()),
|
|
2684
|
+
agentUsed: z7.string().optional(),
|
|
2685
|
+
skillsUsed: z7.array(z7.string()).optional(),
|
|
2686
|
+
// Timestamps
|
|
2687
|
+
startedAt: z7.string(),
|
|
2688
|
+
completedAt: z7.string()
|
|
2689
|
+
});
|
|
2690
|
+
FeatureOutcomeSchema = z7.object({
|
|
2691
|
+
id: z7.string(),
|
|
2692
|
+
// out_feat_xxxxxxxx
|
|
2693
|
+
// Links
|
|
2694
|
+
featureId: z7.string(),
|
|
2695
|
+
featureName: z7.string(),
|
|
2696
|
+
prdId: z7.string().nullable(),
|
|
2697
|
+
// null for legacy features
|
|
2698
|
+
// Version info
|
|
2699
|
+
version: z7.string().optional(),
|
|
2700
|
+
branch: z7.string().optional(),
|
|
2701
|
+
prUrl: z7.string().optional(),
|
|
2702
|
+
// Effort
|
|
2703
|
+
effort: EffortComparisonSchema,
|
|
2704
|
+
// Success (only if PRD exists)
|
|
2705
|
+
success: SuccessTrackingSchema.optional(),
|
|
2706
|
+
// Learnings
|
|
2707
|
+
learnings: LearningsSchema,
|
|
2708
|
+
// ROI
|
|
2709
|
+
roi: ROIAssessmentSchema,
|
|
2710
|
+
// Overall rating
|
|
2711
|
+
rating: QualityScoreSchema,
|
|
2712
|
+
// Task outcomes (sub-tasks)
|
|
2713
|
+
taskOutcomes: z7.array(TaskOutcomeSchema).optional(),
|
|
2714
|
+
// Timestamps
|
|
2715
|
+
startedAt: z7.string(),
|
|
2716
|
+
shippedAt: z7.string(),
|
|
2717
|
+
reviewedAt: z7.string().optional(),
|
|
2718
|
+
// When impact was captured
|
|
2719
|
+
// Metadata
|
|
2720
|
+
reviewedBy: z7.string().optional(),
|
|
2721
|
+
// Who filled out the impact review
|
|
2722
|
+
legacy: z7.boolean().optional()
|
|
2723
|
+
// Legacy feature (no PRD)
|
|
2724
|
+
});
|
|
2725
|
+
AggregateMetricsSchema = z7.object({
|
|
2726
|
+
totalFeatures: z7.number(),
|
|
2727
|
+
averageEstimationAccuracy: z7.number(),
|
|
2728
|
+
// Percentage
|
|
2729
|
+
averageSuccessRate: z7.number(),
|
|
2730
|
+
// Percentage
|
|
2731
|
+
averageROI: z7.number(),
|
|
2732
|
+
// By category
|
|
2733
|
+
bySuccessLevel: z7.object({
|
|
2734
|
+
exceeded: z7.number(),
|
|
2735
|
+
met: z7.number(),
|
|
2736
|
+
partial: z7.number(),
|
|
2737
|
+
failed: z7.number()
|
|
2738
|
+
}),
|
|
2739
|
+
// Variance patterns
|
|
2740
|
+
variancePatterns: z7.array(z7.object({
|
|
2741
|
+
reason: VarianceReasonSchema,
|
|
2742
|
+
count: z7.number(),
|
|
2743
|
+
averageVariance: z7.number()
|
|
2744
|
+
})),
|
|
2745
|
+
// Top learnings (aggregated)
|
|
2746
|
+
topLearnings: z7.array(z7.object({
|
|
2747
|
+
insight: z7.string(),
|
|
2748
|
+
frequency: z7.number()
|
|
2749
|
+
}))
|
|
2750
|
+
});
|
|
2751
|
+
OutcomesJsonSchema = z7.object({
|
|
2752
|
+
outcomes: z7.array(FeatureOutcomeSchema),
|
|
2753
|
+
taskOutcomes: z7.array(TaskOutcomeSchema).optional(),
|
|
2754
|
+
// Standalone task outcomes
|
|
2755
|
+
aggregates: AggregateMetricsSchema.optional(),
|
|
2756
|
+
lastUpdated: z7.string(),
|
|
2757
|
+
lastAggregated: z7.string().optional()
|
|
2758
|
+
});
|
|
2407
2759
|
}
|
|
2408
2760
|
});
|
|
2409
2761
|
|
|
2410
2762
|
// core/schemas/permissions.ts
|
|
2411
|
-
import { z as
|
|
2763
|
+
import { z as z8 } from "zod";
|
|
2412
2764
|
function buildDefaultPermissions() {
|
|
2413
2765
|
const bash = {};
|
|
2414
2766
|
for (const pattern of DEFAULT_BASH_ALLOW) {
|
|
@@ -2441,20 +2793,20 @@ var PermissionLevelSchema, FileOperationSchema, BashPermissionSchema, FilePermis
|
|
|
2441
2793
|
var init_permissions = __esm({
|
|
2442
2794
|
"core/schemas/permissions.ts"() {
|
|
2443
2795
|
"use strict";
|
|
2444
|
-
PermissionLevelSchema =
|
|
2445
|
-
FileOperationSchema =
|
|
2446
|
-
BashPermissionSchema =
|
|
2447
|
-
FilePermissionSchema =
|
|
2448
|
-
WebPermissionSchema =
|
|
2449
|
-
enabled:
|
|
2450
|
-
allowedDomains:
|
|
2451
|
-
blockedDomains:
|
|
2796
|
+
PermissionLevelSchema = z8.enum(["allow", "deny", "ask"]);
|
|
2797
|
+
FileOperationSchema = z8.enum(["read", "write", "delete", "create"]);
|
|
2798
|
+
BashPermissionSchema = z8.record(z8.string(), PermissionLevelSchema);
|
|
2799
|
+
FilePermissionSchema = z8.record(z8.string(), PermissionLevelSchema);
|
|
2800
|
+
WebPermissionSchema = z8.object({
|
|
2801
|
+
enabled: z8.boolean().default(true),
|
|
2802
|
+
allowedDomains: z8.array(z8.string()).optional(),
|
|
2803
|
+
blockedDomains: z8.array(z8.string()).optional()
|
|
2452
2804
|
});
|
|
2453
|
-
PermissionsConfigSchema =
|
|
2805
|
+
PermissionsConfigSchema = z8.object({
|
|
2454
2806
|
/** Bash command permissions - glob patterns */
|
|
2455
2807
|
bash: BashPermissionSchema.optional(),
|
|
2456
2808
|
/** File operation permissions - glob patterns */
|
|
2457
|
-
files:
|
|
2809
|
+
files: z8.object({
|
|
2458
2810
|
read: FilePermissionSchema.optional(),
|
|
2459
2811
|
write: FilePermissionSchema.optional(),
|
|
2460
2812
|
delete: FilePermissionSchema.optional()
|
|
@@ -2462,11 +2814,11 @@ var init_permissions = __esm({
|
|
|
2462
2814
|
/** Web fetch permissions */
|
|
2463
2815
|
web: WebPermissionSchema.optional(),
|
|
2464
2816
|
/** Skill invocation permissions */
|
|
2465
|
-
skills:
|
|
2817
|
+
skills: z8.record(z8.string(), PermissionLevelSchema).optional(),
|
|
2466
2818
|
/** Doom loop protection - prevent infinite retries */
|
|
2467
|
-
doomLoop:
|
|
2468
|
-
enabled:
|
|
2469
|
-
maxRetries:
|
|
2819
|
+
doomLoop: z8.object({
|
|
2820
|
+
enabled: z8.boolean().default(true),
|
|
2821
|
+
maxRetries: z8.number().default(3)
|
|
2470
2822
|
}).optional(),
|
|
2471
2823
|
/** External directory access */
|
|
2472
2824
|
externalDirectories: PermissionLevelSchema.default("ask")
|
|
@@ -2552,56 +2904,19 @@ var init_schemas2 = __esm({
|
|
|
2552
2904
|
});
|
|
2553
2905
|
|
|
2554
2906
|
// core/agentic/template-loader.ts
|
|
2555
|
-
import
|
|
2556
|
-
import
|
|
2557
|
-
function
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2907
|
+
import fs10 from "fs/promises";
|
|
2908
|
+
import path10 from "path";
|
|
2909
|
+
function updateLruOrder(key) {
|
|
2910
|
+
const index = cacheOrder.indexOf(key);
|
|
2911
|
+
if (index > -1) cacheOrder.splice(index, 1);
|
|
2912
|
+
cacheOrder.push(key);
|
|
2913
|
+
}
|
|
2914
|
+
function evictLru() {
|
|
2915
|
+
while (cache.size >= MAX_CACHE_SIZE && cacheOrder.length > 0) {
|
|
2916
|
+
const oldest = cacheOrder.shift();
|
|
2562
2917
|
if (oldest) cache.delete(oldest);
|
|
2563
2918
|
}
|
|
2564
2919
|
}
|
|
2565
|
-
function getWithLru(key) {
|
|
2566
|
-
const value = cache.get(key);
|
|
2567
|
-
if (value !== void 0) {
|
|
2568
|
-
cache.delete(key);
|
|
2569
|
-
cache.set(key, value);
|
|
2570
|
-
}
|
|
2571
|
-
return value;
|
|
2572
|
-
}
|
|
2573
|
-
function parseToolPermissions(lines, startIndex) {
|
|
2574
|
-
const permissions = {};
|
|
2575
|
-
let i = startIndex;
|
|
2576
|
-
let currentTool = null;
|
|
2577
|
-
while (i < lines.length) {
|
|
2578
|
-
const line = lines[i];
|
|
2579
|
-
const trimmed = line.trim();
|
|
2580
|
-
if (line.length > 0 && !line.startsWith(" ") && !line.startsWith(" ")) {
|
|
2581
|
-
break;
|
|
2582
|
-
}
|
|
2583
|
-
const toolMatch = line.match(/^ {2}(\w+):$/);
|
|
2584
|
-
if (toolMatch) {
|
|
2585
|
-
currentTool = toolMatch[1];
|
|
2586
|
-
permissions[currentTool] = {};
|
|
2587
|
-
i++;
|
|
2588
|
-
continue;
|
|
2589
|
-
}
|
|
2590
|
-
const permMatch = line.match(/^ {4}(allow|ask|deny):\s*\[(.+)\]/);
|
|
2591
|
-
if (permMatch && currentTool) {
|
|
2592
|
-
const [, permType, arrayContent] = permMatch;
|
|
2593
|
-
permissions[currentTool][permType] = arrayContent.split(",").map((v) => v.trim().replace(/^["']|["']$/g, ""));
|
|
2594
|
-
i++;
|
|
2595
|
-
continue;
|
|
2596
|
-
}
|
|
2597
|
-
if (trimmed === "") {
|
|
2598
|
-
i++;
|
|
2599
|
-
continue;
|
|
2600
|
-
}
|
|
2601
|
-
i++;
|
|
2602
|
-
}
|
|
2603
|
-
return { permissions, endIndex: i };
|
|
2604
|
-
}
|
|
2605
2920
|
function parseFrontmatter(content) {
|
|
2606
2921
|
const frontmatterRegex = /^---\n([\s\S]+?)\n---\n([\s\S]*)$/;
|
|
2607
2922
|
const match = content.match(frontmatterRegex);
|
|
@@ -2610,39 +2925,31 @@ function parseFrontmatter(content) {
|
|
|
2610
2925
|
}
|
|
2611
2926
|
const [, frontmatterText, mainContent] = match;
|
|
2612
2927
|
const frontmatter = {};
|
|
2613
|
-
|
|
2614
|
-
for (let i = 0; i < lines.length; i++) {
|
|
2615
|
-
const line = lines[i];
|
|
2928
|
+
frontmatterText.split("\n").forEach((line) => {
|
|
2616
2929
|
const [key, ...valueParts] = line.split(":");
|
|
2617
|
-
if (
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
frontmatter["tool-permissions"] = permissions;
|
|
2625
|
-
i = endIndex - 1;
|
|
2626
|
-
continue;
|
|
2627
|
-
}
|
|
2628
|
-
if (value.startsWith("[") && value.endsWith("]")) {
|
|
2629
|
-
frontmatter[keyTrimmed] = value.slice(1, -1).split(",").map((v) => v.trim());
|
|
2630
|
-
} else if (value) {
|
|
2631
|
-
frontmatter[keyTrimmed] = value.replace(/^["']|["']$/g, "");
|
|
2930
|
+
if (key && valueParts.length > 0) {
|
|
2931
|
+
const value = valueParts.join(":").trim();
|
|
2932
|
+
if (value.startsWith("[") && value.endsWith("]")) {
|
|
2933
|
+
frontmatter[key.trim()] = value.slice(1, -1).split(",").map((v) => v.trim());
|
|
2934
|
+
} else {
|
|
2935
|
+
frontmatter[key.trim()] = value.replace(/^["']|["']$/g, "");
|
|
2936
|
+
}
|
|
2632
2937
|
}
|
|
2633
|
-
}
|
|
2938
|
+
});
|
|
2634
2939
|
return { frontmatter, content: mainContent.trim() };
|
|
2635
2940
|
}
|
|
2636
2941
|
async function load(commandName) {
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
return
|
|
2942
|
+
if (cache.has(commandName)) {
|
|
2943
|
+
updateLruOrder(commandName);
|
|
2944
|
+
return cache.get(commandName);
|
|
2640
2945
|
}
|
|
2641
|
-
const templatePath =
|
|
2946
|
+
const templatePath = path10.join(TEMPLATES_DIR, `${commandName}.md`);
|
|
2642
2947
|
try {
|
|
2643
|
-
const rawContent = await
|
|
2948
|
+
const rawContent = await fs10.readFile(templatePath, "utf-8");
|
|
2644
2949
|
const parsed = parseFrontmatter(rawContent);
|
|
2645
|
-
|
|
2950
|
+
evictLru();
|
|
2951
|
+
cache.set(commandName, parsed);
|
|
2952
|
+
cacheOrder.push(commandName);
|
|
2646
2953
|
return parsed;
|
|
2647
2954
|
} catch {
|
|
2648
2955
|
throw TemplateError.notFound(commandName);
|
|
@@ -2654,18 +2961,19 @@ async function getAllowedTools(commandName) {
|
|
|
2654
2961
|
}
|
|
2655
2962
|
function clearCache() {
|
|
2656
2963
|
cache.clear();
|
|
2964
|
+
cacheOrder.length = 0;
|
|
2657
2965
|
}
|
|
2658
|
-
var TEMPLATES_DIR, MAX_CACHE_SIZE, cache, template_loader_default;
|
|
2966
|
+
var TEMPLATES_DIR, MAX_CACHE_SIZE, cache, cacheOrder, template_loader_default;
|
|
2659
2967
|
var init_template_loader = __esm({
|
|
2660
2968
|
"core/agentic/template-loader.ts"() {
|
|
2661
2969
|
"use strict";
|
|
2662
2970
|
init_errors();
|
|
2663
|
-
TEMPLATES_DIR =
|
|
2971
|
+
TEMPLATES_DIR = path10.join(__dirname, "..", "..", "templates", "commands");
|
|
2664
2972
|
MAX_CACHE_SIZE = 50;
|
|
2665
2973
|
cache = /* @__PURE__ */ new Map();
|
|
2666
|
-
|
|
2667
|
-
__name(
|
|
2668
|
-
__name(
|
|
2974
|
+
cacheOrder = [];
|
|
2975
|
+
__name(updateLruOrder, "updateLruOrder");
|
|
2976
|
+
__name(evictLru, "evictLru");
|
|
2669
2977
|
__name(parseFrontmatter, "parseFrontmatter");
|
|
2670
2978
|
__name(load, "load");
|
|
2671
2979
|
__name(getAllowedTools, "getAllowedTools");
|
|
@@ -2680,7 +2988,7 @@ var init_template_loader = __esm({
|
|
|
2680
2988
|
});
|
|
2681
2989
|
|
|
2682
2990
|
// core/agentic/context-builder.ts
|
|
2683
|
-
import
|
|
2991
|
+
import fs11 from "fs/promises";
|
|
2684
2992
|
var ContextBuilder, contextBuilder, context_builder_default;
|
|
2685
2993
|
var init_context_builder = __esm({
|
|
2686
2994
|
"core/agentic/context-builder.ts"() {
|
|
@@ -2758,7 +3066,7 @@ var init_context_builder = __esm({
|
|
|
2758
3066
|
for (const [, filePath] of filteredEntries) {
|
|
2759
3067
|
if (this._cache.has(filePath)) {
|
|
2760
3068
|
try {
|
|
2761
|
-
const stat = await
|
|
3069
|
+
const stat = await fs11.stat(filePath);
|
|
2762
3070
|
const cachedMtime = this._mtimes.get(filePath);
|
|
2763
3071
|
if (!cachedMtime || stat.mtimeMs > cachedMtime) {
|
|
2764
3072
|
this._cache.delete(filePath);
|
|
@@ -2781,7 +3089,7 @@ var init_context_builder = __esm({
|
|
|
2781
3089
|
if (uncachedEntries.length > 0) {
|
|
2782
3090
|
const readPromises = uncachedEntries.map(async ([key, filePath]) => {
|
|
2783
3091
|
try {
|
|
2784
|
-
const [content, stat] = await Promise.all([
|
|
3092
|
+
const [content, stat] = await Promise.all([fs11.readFile(filePath, "utf-8"), fs11.stat(filePath)]);
|
|
2785
3093
|
return { key, filePath, content, mtime: stat.mtimeMs };
|
|
2786
3094
|
} catch {
|
|
2787
3095
|
return { key, filePath, content: null, mtime: null };
|
|
@@ -2851,7 +3159,7 @@ var init_context_builder = __esm({
|
|
|
2851
3159
|
if (uncachedPaths.length > 0) {
|
|
2852
3160
|
const readPromises = uncachedPaths.map(async (filePath) => {
|
|
2853
3161
|
try {
|
|
2854
|
-
const content = await
|
|
3162
|
+
const content = await fs11.readFile(filePath, "utf-8");
|
|
2855
3163
|
return { filePath, content };
|
|
2856
3164
|
} catch {
|
|
2857
3165
|
return { filePath, content: null };
|
|
@@ -2882,7 +3190,7 @@ var init_context_builder = __esm({
|
|
|
2882
3190
|
*/
|
|
2883
3191
|
async fileExists(filePath) {
|
|
2884
3192
|
try {
|
|
2885
|
-
await
|
|
3193
|
+
await fs11.access(filePath);
|
|
2886
3194
|
return true;
|
|
2887
3195
|
} catch {
|
|
2888
3196
|
return false;
|
|
@@ -3087,8 +3395,8 @@ var init_cache = __esm({
|
|
|
3087
3395
|
});
|
|
3088
3396
|
|
|
3089
3397
|
// core/storage/storage-manager.ts
|
|
3090
|
-
import
|
|
3091
|
-
import
|
|
3398
|
+
import fs12 from "fs/promises";
|
|
3399
|
+
import path11 from "path";
|
|
3092
3400
|
var StorageManager;
|
|
3093
3401
|
var init_storage_manager = __esm({
|
|
3094
3402
|
"core/storage/storage-manager.ts"() {
|
|
@@ -3131,7 +3439,7 @@ var init_storage_manager = __esm({
|
|
|
3131
3439
|
}
|
|
3132
3440
|
const filePath = this.getStoragePath(projectId);
|
|
3133
3441
|
try {
|
|
3134
|
-
const content = await
|
|
3442
|
+
const content = await fs12.readFile(filePath, "utf-8");
|
|
3135
3443
|
const data = JSON.parse(content);
|
|
3136
3444
|
this.cache.set(projectId, data);
|
|
3137
3445
|
return data;
|
|
@@ -3145,13 +3453,13 @@ var init_storage_manager = __esm({
|
|
|
3145
3453
|
async write(projectId, data) {
|
|
3146
3454
|
const storagePath = this.getStoragePath(projectId);
|
|
3147
3455
|
const contextPath = this.getContextPath(projectId, this.getMdFilename());
|
|
3148
|
-
await
|
|
3149
|
-
await
|
|
3456
|
+
await fs12.mkdir(path11.dirname(storagePath), { recursive: true });
|
|
3457
|
+
await fs12.mkdir(path11.dirname(contextPath), { recursive: true });
|
|
3150
3458
|
const tempPath = `${storagePath}.${Date.now()}.tmp`;
|
|
3151
|
-
await
|
|
3152
|
-
await
|
|
3459
|
+
await fs12.writeFile(tempPath, JSON.stringify(data, null, 2), "utf-8");
|
|
3460
|
+
await fs12.rename(tempPath, storagePath);
|
|
3153
3461
|
const md2 = this.toMarkdown(data);
|
|
3154
|
-
await
|
|
3462
|
+
await fs12.writeFile(contextPath, md2, "utf-8");
|
|
3155
3463
|
this.cache.set(projectId, data);
|
|
3156
3464
|
}
|
|
3157
3465
|
/**
|
|
@@ -3199,7 +3507,7 @@ var init_storage_manager = __esm({
|
|
|
3199
3507
|
async exists(projectId) {
|
|
3200
3508
|
const filePath = this.getStoragePath(projectId);
|
|
3201
3509
|
try {
|
|
3202
|
-
await
|
|
3510
|
+
await fs12.access(filePath);
|
|
3203
3511
|
return true;
|
|
3204
3512
|
} catch {
|
|
3205
3513
|
return false;
|
|
@@ -4250,9 +4558,9 @@ var init_shipped_storage = __esm({
|
|
|
4250
4558
|
});
|
|
4251
4559
|
|
|
4252
4560
|
// core/storage/storage.ts
|
|
4253
|
-
import
|
|
4254
|
-
import
|
|
4255
|
-
import
|
|
4561
|
+
import fs13 from "fs/promises";
|
|
4562
|
+
import path12 from "path";
|
|
4563
|
+
import os6 from "os";
|
|
4256
4564
|
function getStorage(projectId) {
|
|
4257
4565
|
return new FileStorage(projectId);
|
|
4258
4566
|
}
|
|
@@ -4269,7 +4577,7 @@ var init_storage = __esm({
|
|
|
4269
4577
|
basePath;
|
|
4270
4578
|
constructor(projectId) {
|
|
4271
4579
|
this.projectId = projectId;
|
|
4272
|
-
this.basePath =
|
|
4580
|
+
this.basePath = path12.join(os6.homedir(), ".prjct-cli/projects", projectId, "data");
|
|
4273
4581
|
}
|
|
4274
4582
|
/**
|
|
4275
4583
|
* Convert path array to file path
|
|
@@ -4278,17 +4586,17 @@ var init_storage = __esm({
|
|
|
4278
4586
|
*/
|
|
4279
4587
|
pathToFile(pathArray) {
|
|
4280
4588
|
if (pathArray.length === 1) {
|
|
4281
|
-
return
|
|
4589
|
+
return path12.join(this.basePath, `${pathArray[0]}.json`);
|
|
4282
4590
|
}
|
|
4283
4591
|
const dir = pathArray[0] + "s";
|
|
4284
4592
|
const rest = pathArray.slice(1);
|
|
4285
4593
|
const filename = rest.join("/") + ".json";
|
|
4286
|
-
return
|
|
4594
|
+
return path12.join(this.basePath, dir, filename);
|
|
4287
4595
|
}
|
|
4288
4596
|
async write(pathArray, data) {
|
|
4289
4597
|
const filePath = this.pathToFile(pathArray);
|
|
4290
|
-
await
|
|
4291
|
-
await
|
|
4598
|
+
await fs13.mkdir(path12.dirname(filePath), { recursive: true });
|
|
4599
|
+
await fs13.writeFile(filePath, JSON.stringify(data, null, 2), "utf-8");
|
|
4292
4600
|
eventBus.publish({
|
|
4293
4601
|
type: inferEventType(pathArray, "write"),
|
|
4294
4602
|
path: pathArray,
|
|
@@ -4303,16 +4611,16 @@ var init_storage = __esm({
|
|
|
4303
4611
|
async read(pathArray) {
|
|
4304
4612
|
const filePath = this.pathToFile(pathArray);
|
|
4305
4613
|
try {
|
|
4306
|
-
const content = await
|
|
4614
|
+
const content = await fs13.readFile(filePath, "utf-8");
|
|
4307
4615
|
return JSON.parse(content);
|
|
4308
4616
|
} catch {
|
|
4309
4617
|
return null;
|
|
4310
4618
|
}
|
|
4311
4619
|
}
|
|
4312
4620
|
async list(prefix) {
|
|
4313
|
-
const dir =
|
|
4621
|
+
const dir = path12.join(this.basePath, prefix[0] + "s");
|
|
4314
4622
|
try {
|
|
4315
|
-
const files = await
|
|
4623
|
+
const files = await fs13.readdir(dir);
|
|
4316
4624
|
return files.filter((f) => f.endsWith(".json") && f !== "index.json").map((f) => [...prefix, f.replace(".json", "")]);
|
|
4317
4625
|
} catch {
|
|
4318
4626
|
return [];
|
|
@@ -4321,7 +4629,7 @@ var init_storage = __esm({
|
|
|
4321
4629
|
async delete(pathArray) {
|
|
4322
4630
|
const filePath = this.pathToFile(pathArray);
|
|
4323
4631
|
try {
|
|
4324
|
-
await
|
|
4632
|
+
await fs13.unlink(filePath);
|
|
4325
4633
|
eventBus.publish({
|
|
4326
4634
|
type: inferEventType(pathArray, "delete"),
|
|
4327
4635
|
path: pathArray,
|
|
@@ -4338,7 +4646,7 @@ var init_storage = __esm({
|
|
|
4338
4646
|
async exists(pathArray) {
|
|
4339
4647
|
const filePath = this.pathToFile(pathArray);
|
|
4340
4648
|
try {
|
|
4341
|
-
await
|
|
4649
|
+
await fs13.access(filePath);
|
|
4342
4650
|
return true;
|
|
4343
4651
|
} catch {
|
|
4344
4652
|
return false;
|
|
@@ -4348,10 +4656,10 @@ var init_storage = __esm({
|
|
|
4348
4656
|
* Update collection index
|
|
4349
4657
|
*/
|
|
4350
4658
|
async updateIndex(collection, id, action) {
|
|
4351
|
-
const indexPath =
|
|
4659
|
+
const indexPath = path12.join(this.basePath, collection + "s", "index.json");
|
|
4352
4660
|
let index = { ids: [], updatedAt: "" };
|
|
4353
4661
|
try {
|
|
4354
|
-
const content = await
|
|
4662
|
+
const content = await fs13.readFile(indexPath, "utf-8");
|
|
4355
4663
|
index = JSON.parse(content);
|
|
4356
4664
|
} catch {
|
|
4357
4665
|
}
|
|
@@ -4361,8 +4669,8 @@ var init_storage = __esm({
|
|
|
4361
4669
|
index.ids = index.ids.filter((i) => i !== id);
|
|
4362
4670
|
}
|
|
4363
4671
|
index.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
4364
|
-
await
|
|
4365
|
-
await
|
|
4672
|
+
await fs13.mkdir(path12.dirname(indexPath), { recursive: true });
|
|
4673
|
+
await fs13.writeFile(indexPath, JSON.stringify(index, null, 2), "utf-8");
|
|
4366
4674
|
}
|
|
4367
4675
|
};
|
|
4368
4676
|
__name(getStorage, "getStorage");
|
|
@@ -4383,7 +4691,7 @@ var init_storage2 = __esm({
|
|
|
4383
4691
|
});
|
|
4384
4692
|
|
|
4385
4693
|
// core/outcomes/recorder.ts
|
|
4386
|
-
import
|
|
4694
|
+
import path13 from "path";
|
|
4387
4695
|
var OUTCOMES_DIR, OUTCOMES_FILE, OutcomeRecorder, outcomeRecorder, recorder_default;
|
|
4388
4696
|
var init_recorder = __esm({
|
|
4389
4697
|
"core/outcomes/recorder.ts"() {
|
|
@@ -4402,13 +4710,13 @@ var init_recorder = __esm({
|
|
|
4402
4710
|
*/
|
|
4403
4711
|
getOutcomesDir(projectId) {
|
|
4404
4712
|
const globalPath = path_manager_default.getGlobalProjectPath(projectId);
|
|
4405
|
-
return
|
|
4713
|
+
return path13.join(globalPath, OUTCOMES_DIR);
|
|
4406
4714
|
}
|
|
4407
4715
|
/**
|
|
4408
4716
|
* Get outcomes file path for a project.
|
|
4409
4717
|
*/
|
|
4410
4718
|
getOutcomesPath(projectId) {
|
|
4411
|
-
return
|
|
4719
|
+
return path13.join(this.getOutcomesDir(projectId), OUTCOMES_FILE);
|
|
4412
4720
|
}
|
|
4413
4721
|
/**
|
|
4414
4722
|
* Record an outcome.
|
|
@@ -4419,7 +4727,7 @@ var init_recorder = __esm({
|
|
|
4419
4727
|
id: generateUUID()
|
|
4420
4728
|
};
|
|
4421
4729
|
const outcomesPath = this.getOutcomesPath(projectId);
|
|
4422
|
-
await ensureDir(
|
|
4730
|
+
await ensureDir(path13.dirname(outcomesPath));
|
|
4423
4731
|
await appendLine(outcomesPath, JSON.stringify(outcome));
|
|
4424
4732
|
return outcome;
|
|
4425
4733
|
}
|
|
@@ -4786,6 +5094,21 @@ var init_memory = __esm({
|
|
|
4786
5094
|
}
|
|
4787
5095
|
});
|
|
4788
5096
|
|
|
5097
|
+
// core/integrations/issue-tracker/types.ts
|
|
5098
|
+
var init_types = __esm({
|
|
5099
|
+
"core/integrations/issue-tracker/types.ts"() {
|
|
5100
|
+
"use strict";
|
|
5101
|
+
}
|
|
5102
|
+
});
|
|
5103
|
+
|
|
5104
|
+
// core/types/integrations.ts
|
|
5105
|
+
var init_integrations = __esm({
|
|
5106
|
+
"core/types/integrations.ts"() {
|
|
5107
|
+
"use strict";
|
|
5108
|
+
init_types();
|
|
5109
|
+
}
|
|
5110
|
+
});
|
|
5111
|
+
|
|
4789
5112
|
// core/types/bus.ts
|
|
4790
5113
|
var init_bus = __esm({
|
|
4791
5114
|
"core/types/bus.ts"() {
|
|
@@ -4794,11 +5117,12 @@ var init_bus = __esm({
|
|
|
4794
5117
|
});
|
|
4795
5118
|
|
|
4796
5119
|
// core/types/index.ts
|
|
4797
|
-
var
|
|
5120
|
+
var init_types2 = __esm({
|
|
4798
5121
|
"core/types/index.ts"() {
|
|
4799
5122
|
"use strict";
|
|
4800
5123
|
init_fs();
|
|
4801
5124
|
init_memory();
|
|
5125
|
+
init_integrations();
|
|
4802
5126
|
init_bus();
|
|
4803
5127
|
}
|
|
4804
5128
|
});
|
|
@@ -4809,13 +5133,13 @@ var init_outcomes2 = __esm({
|
|
|
4809
5133
|
"use strict";
|
|
4810
5134
|
init_recorder();
|
|
4811
5135
|
init_analyzer();
|
|
4812
|
-
|
|
5136
|
+
init_types2();
|
|
4813
5137
|
}
|
|
4814
5138
|
});
|
|
4815
5139
|
|
|
4816
5140
|
// core/agentic/prompt-builder.ts
|
|
4817
|
-
import
|
|
4818
|
-
import
|
|
5141
|
+
import fs14 from "fs";
|
|
5142
|
+
import path14 from "path";
|
|
4819
5143
|
var PromptBuilder, promptBuilder, prompt_builder_default;
|
|
4820
5144
|
var init_prompt_builder = __esm({
|
|
4821
5145
|
"core/agentic/prompt-builder.ts"() {
|
|
@@ -4849,14 +5173,14 @@ var init_prompt_builder = __esm({
|
|
|
4849
5173
|
*/
|
|
4850
5174
|
loadChecklists() {
|
|
4851
5175
|
if (this._checklistsCache) return this._checklistsCache;
|
|
4852
|
-
const checklistsDir =
|
|
5176
|
+
const checklistsDir = path14.join(__dirname, "..", "..", "templates", "checklists");
|
|
4853
5177
|
const checklists = {};
|
|
4854
5178
|
try {
|
|
4855
|
-
if (
|
|
4856
|
-
const files =
|
|
5179
|
+
if (fs14.existsSync(checklistsDir)) {
|
|
5180
|
+
const files = fs14.readdirSync(checklistsDir).filter((f) => f.endsWith(".md"));
|
|
4857
5181
|
for (const file of files) {
|
|
4858
5182
|
const name = file.replace(".md", "");
|
|
4859
|
-
const content =
|
|
5183
|
+
const content = fs14.readFileSync(path14.join(checklistsDir, file), "utf-8");
|
|
4860
5184
|
checklists[name] = content;
|
|
4861
5185
|
}
|
|
4862
5186
|
}
|
|
@@ -4957,10 +5281,10 @@ var init_prompt_builder = __esm({
|
|
|
4957
5281
|
*/
|
|
4958
5282
|
loadChecklistRouting() {
|
|
4959
5283
|
if (this._checklistRoutingCache) return this._checklistRoutingCache;
|
|
4960
|
-
const routingPath =
|
|
5284
|
+
const routingPath = path14.join(__dirname, "..", "..", "templates", "agentic", "checklist-routing.md");
|
|
4961
5285
|
try {
|
|
4962
|
-
if (
|
|
4963
|
-
this._checklistRoutingCache =
|
|
5286
|
+
if (fs14.existsSync(routingPath)) {
|
|
5287
|
+
this._checklistRoutingCache = fs14.readFileSync(routingPath, "utf-8");
|
|
4964
5288
|
}
|
|
4965
5289
|
} catch {
|
|
4966
5290
|
}
|
|
@@ -4999,7 +5323,7 @@ var init_prompt_builder = __esm({
|
|
|
4999
5323
|
const parts = [];
|
|
5000
5324
|
this._currentContext = context;
|
|
5001
5325
|
const commandName = template.frontmatter?.name?.replace("p:", "") || "";
|
|
5002
|
-
const agentCommands = ["
|
|
5326
|
+
const agentCommands = ["now", "build", "feature", "design", "fix", "bug", "test", "work", "cleanup", "spec"];
|
|
5003
5327
|
const needsAgent = agentCommands.includes(commandName);
|
|
5004
5328
|
if (agent && needsAgent) {
|
|
5005
5329
|
parts.push(`# AGENT: ${agent.name}
|
|
@@ -5046,7 +5370,7 @@ Read files before modifying.
|
|
|
5046
5370
|
|
|
5047
5371
|
`);
|
|
5048
5372
|
}
|
|
5049
|
-
const codeCommands = ["
|
|
5373
|
+
const codeCommands = ["now", "build", "feature", "design", "cleanup", "fix", "bug", "test", "init", "spec", "work"];
|
|
5050
5374
|
const needsPatterns = codeCommands.includes(commandName);
|
|
5051
5375
|
const codePatternsContent = state?.codePatterns || "";
|
|
5052
5376
|
if (needsPatterns && codePatternsContent && codePatternsContent.trim()) {
|
|
@@ -5196,71 +5520,6 @@ ${content.substring(0, 500)}... (truncated, use Read tool for full content)`
|
|
|
5196
5520
|
const result = parts.join("\n").substring(0, 800);
|
|
5197
5521
|
return result || null;
|
|
5198
5522
|
}
|
|
5199
|
-
/**
|
|
5200
|
-
* Claude Code subagents that can be invoked via @ notation
|
|
5201
|
-
*/
|
|
5202
|
-
CLAUDE_SUBAGENTS = ["explore", "general", "plan"];
|
|
5203
|
-
/**
|
|
5204
|
-
* Parse @ agent mentions from input
|
|
5205
|
-
* Separates prjct agents from Claude Code subagents
|
|
5206
|
-
* @example "@frontend @explore add dark mode" -> { prjctAgents: ["frontend"], claudeSubagents: ["explore"], cleanInput: "add dark mode" }
|
|
5207
|
-
*/
|
|
5208
|
-
parseAgentMentions(input) {
|
|
5209
|
-
if (!input) return { prjctAgents: [], claudeSubagents: [], cleanInput: "" };
|
|
5210
|
-
const mentionPattern = /@(\w+)/g;
|
|
5211
|
-
const prjctAgents = [];
|
|
5212
|
-
const claudeSubagents = [];
|
|
5213
|
-
let match;
|
|
5214
|
-
while ((match = mentionPattern.exec(input)) !== null) {
|
|
5215
|
-
const name = match[1].toLowerCase();
|
|
5216
|
-
if (this.CLAUDE_SUBAGENTS.includes(name)) {
|
|
5217
|
-
claudeSubagents.push(name);
|
|
5218
|
-
} else {
|
|
5219
|
-
prjctAgents.push(name);
|
|
5220
|
-
}
|
|
5221
|
-
}
|
|
5222
|
-
const cleanInput = input.replace(mentionPattern, "").trim();
|
|
5223
|
-
return { prjctAgents, claudeSubagents, cleanInput };
|
|
5224
|
-
}
|
|
5225
|
-
/**
|
|
5226
|
-
* Build Claude subagent instructions for the prompt
|
|
5227
|
-
*/
|
|
5228
|
-
buildSubagentInstructions(claudeSubagents) {
|
|
5229
|
-
if (!claudeSubagents.length) return "";
|
|
5230
|
-
const instructions = claudeSubagents.map((sub) => {
|
|
5231
|
-
switch (sub) {
|
|
5232
|
-
case "explore":
|
|
5233
|
-
return "- USE Task tool with subagent_type=Explore for fast codebase exploration";
|
|
5234
|
-
case "general":
|
|
5235
|
-
return "- USE Task tool with subagent_type=general-purpose for complex multi-step research";
|
|
5236
|
-
case "plan":
|
|
5237
|
-
return "- USE Task tool with subagent_type=Plan for architecture design";
|
|
5238
|
-
default:
|
|
5239
|
-
return null;
|
|
5240
|
-
}
|
|
5241
|
-
}).filter(Boolean);
|
|
5242
|
-
if (!instructions.length) return "";
|
|
5243
|
-
return `
|
|
5244
|
-
## CLAUDE SUBAGENT INSTRUCTIONS
|
|
5245
|
-
${instructions.join("\n")}
|
|
5246
|
-
`;
|
|
5247
|
-
}
|
|
5248
|
-
/**
|
|
5249
|
-
* Build tool permissions section from template frontmatter
|
|
5250
|
-
*/
|
|
5251
|
-
buildToolPermissions(toolPermissions) {
|
|
5252
|
-
if (!toolPermissions) return "";
|
|
5253
|
-
const parts = ["\n## TOOL PERMISSIONS\n", "Check these BEFORE executing:\n"];
|
|
5254
|
-
for (const [tool, rules] of Object.entries(toolPermissions)) {
|
|
5255
|
-
parts.push(`
|
|
5256
|
-
**${tool}:**`);
|
|
5257
|
-
if (rules.allow?.length) parts.push(`- ALLOW: ${rules.allow.join(", ")}`);
|
|
5258
|
-
if (rules.ask?.length) parts.push(`- ASK USER: ${rules.ask.join(", ")}`);
|
|
5259
|
-
if (rules.deny?.length) parts.push(`- NEVER: ${rules.deny.join(", ")}`);
|
|
5260
|
-
}
|
|
5261
|
-
parts.push("\n\u26A0\uFE0F DENY = Never execute. ASK = Confirm with user first.\n");
|
|
5262
|
-
return parts.join("\n");
|
|
5263
|
-
}
|
|
5264
5523
|
/**
|
|
5265
5524
|
* Build critical anti-hallucination rules section
|
|
5266
5525
|
*/
|
|
@@ -5283,7 +5542,7 @@ Context: ${fileCount} files available. Read what you need.
|
|
|
5283
5542
|
});
|
|
5284
5543
|
|
|
5285
5544
|
// core/agentic/tool-registry.ts
|
|
5286
|
-
import
|
|
5545
|
+
import fs15 from "fs/promises";
|
|
5287
5546
|
import { exec as exec2 } from "child_process";
|
|
5288
5547
|
import { promisify as promisify2 } from "util";
|
|
5289
5548
|
var execAsync, toolRegistry, tool_registry_default;
|
|
@@ -5328,14 +5587,14 @@ var init_tool_registry = __esm({
|
|
|
5328
5587
|
};
|
|
5329
5588
|
toolRegistry.register("Read", async (filePath) => {
|
|
5330
5589
|
try {
|
|
5331
|
-
return await
|
|
5590
|
+
return await fs15.readFile(filePath, "utf-8");
|
|
5332
5591
|
} catch {
|
|
5333
5592
|
return null;
|
|
5334
5593
|
}
|
|
5335
5594
|
});
|
|
5336
5595
|
toolRegistry.register("Write", async (filePath, content) => {
|
|
5337
5596
|
try {
|
|
5338
|
-
await
|
|
5597
|
+
await fs15.writeFile(filePath, content, "utf-8");
|
|
5339
5598
|
return true;
|
|
5340
5599
|
} catch {
|
|
5341
5600
|
return false;
|
|
@@ -5806,10 +6065,10 @@ var init_chain_of_thought = __esm({
|
|
|
5806
6065
|
});
|
|
5807
6066
|
|
|
5808
6067
|
// core/utils/jsonl-helper.ts
|
|
5809
|
-
import
|
|
6068
|
+
import fs16 from "fs/promises";
|
|
5810
6069
|
import fsSync from "fs";
|
|
5811
6070
|
import readline from "readline";
|
|
5812
|
-
import
|
|
6071
|
+
import path15 from "path";
|
|
5813
6072
|
function parseJsonLines(content) {
|
|
5814
6073
|
const lines = content.split("\n").filter((line) => line.trim());
|
|
5815
6074
|
const entries = [];
|
|
@@ -5826,7 +6085,7 @@ function stringifyJsonLines(objects) {
|
|
|
5826
6085
|
}
|
|
5827
6086
|
async function readJsonLines(filePath) {
|
|
5828
6087
|
try {
|
|
5829
|
-
const content = await
|
|
6088
|
+
const content = await fs16.readFile(filePath, "utf-8");
|
|
5830
6089
|
return parseJsonLines(content);
|
|
5831
6090
|
} catch (error) {
|
|
5832
6091
|
if (isNotFoundError(error)) {
|
|
@@ -5837,15 +6096,15 @@ async function readJsonLines(filePath) {
|
|
|
5837
6096
|
}
|
|
5838
6097
|
async function writeJsonLines(filePath, objects) {
|
|
5839
6098
|
const content = stringifyJsonLines(objects);
|
|
5840
|
-
await
|
|
6099
|
+
await fs16.writeFile(filePath, content, "utf-8");
|
|
5841
6100
|
}
|
|
5842
6101
|
async function appendJsonLine(filePath, object) {
|
|
5843
6102
|
const line = JSON.stringify(object) + "\n";
|
|
5844
|
-
await
|
|
6103
|
+
await fs16.appendFile(filePath, line, "utf-8");
|
|
5845
6104
|
}
|
|
5846
6105
|
async function appendJsonLines(filePath, objects) {
|
|
5847
6106
|
const content = stringifyJsonLines(objects);
|
|
5848
|
-
await
|
|
6107
|
+
await fs16.appendFile(filePath, content, "utf-8");
|
|
5849
6108
|
}
|
|
5850
6109
|
async function filterJsonLines(filePath, predicate) {
|
|
5851
6110
|
const entries = await readJsonLines(filePath);
|
|
@@ -5853,7 +6112,7 @@ async function filterJsonLines(filePath, predicate) {
|
|
|
5853
6112
|
}
|
|
5854
6113
|
async function countJsonLines(filePath) {
|
|
5855
6114
|
try {
|
|
5856
|
-
const content = await
|
|
6115
|
+
const content = await fs16.readFile(filePath, "utf-8");
|
|
5857
6116
|
const lines = content.split("\n").filter((line) => line.trim());
|
|
5858
6117
|
return lines.length;
|
|
5859
6118
|
} catch (error) {
|
|
@@ -5912,7 +6171,7 @@ async function readJsonLinesStreaming(filePath, maxLines = 1e3) {
|
|
|
5912
6171
|
}
|
|
5913
6172
|
async function getFileSizeMB(filePath) {
|
|
5914
6173
|
try {
|
|
5915
|
-
const stats = await
|
|
6174
|
+
const stats = await fs16.stat(filePath);
|
|
5916
6175
|
return stats.size / (1024 * 1024);
|
|
5917
6176
|
} catch (error) {
|
|
5918
6177
|
if (isNotFoundError(error)) {
|
|
@@ -5927,12 +6186,12 @@ async function rotateJsonLinesIfNeeded(filePath, maxSizeMB = 10) {
|
|
|
5927
6186
|
return false;
|
|
5928
6187
|
}
|
|
5929
6188
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
5930
|
-
const dir =
|
|
5931
|
-
const ext =
|
|
5932
|
-
const base =
|
|
5933
|
-
const archivePath =
|
|
5934
|
-
await
|
|
5935
|
-
console.log(`\u{1F4E6} Rotated ${
|
|
6189
|
+
const dir = path15.dirname(filePath);
|
|
6190
|
+
const ext = path15.extname(filePath);
|
|
6191
|
+
const base = path15.basename(filePath, ext);
|
|
6192
|
+
const archivePath = path15.join(dir, `${base}-${timestamp}${ext}`);
|
|
6193
|
+
await fs16.rename(filePath, archivePath);
|
|
6194
|
+
console.log(`\u{1F4E6} Rotated ${path15.basename(filePath)} (${sizeMB.toFixed(1)}MB) \u2192 ${path15.basename(archivePath)}`);
|
|
5936
6195
|
return true;
|
|
5937
6196
|
}
|
|
5938
6197
|
async function appendJsonLineWithRotation(filePath, object, maxSizeMB = 10) {
|
|
@@ -5944,7 +6203,7 @@ async function checkFileSizeWarning(filePath, warnThresholdMB = 50) {
|
|
|
5944
6203
|
const isLarge = sizeMB > warnThresholdMB;
|
|
5945
6204
|
if (isLarge) {
|
|
5946
6205
|
console.warn(
|
|
5947
|
-
`\u26A0\uFE0F Large file detected: ${
|
|
6206
|
+
`\u26A0\uFE0F Large file detected: ${path15.basename(filePath)} (${sizeMB.toFixed(1)}MB). Reading may use significant memory.`
|
|
5948
6207
|
);
|
|
5949
6208
|
}
|
|
5950
6209
|
return { sizeMB, isLarge };
|
|
@@ -5994,8 +6253,8 @@ var init_jsonl_helper = __esm({
|
|
|
5994
6253
|
});
|
|
5995
6254
|
|
|
5996
6255
|
// core/agentic/memory-system.ts
|
|
5997
|
-
import
|
|
5998
|
-
import
|
|
6256
|
+
import fs17 from "fs/promises";
|
|
6257
|
+
import path16 from "path";
|
|
5999
6258
|
var CachedStore, SessionStore, HistoryStore, PatternStore, SemanticMemories, MemorySystem, memorySystem, memory_system_default;
|
|
6000
6259
|
var init_memory_system = __esm({
|
|
6001
6260
|
"core/agentic/memory-system.ts"() {
|
|
@@ -6025,12 +6284,12 @@ var init_memory_system = __esm({
|
|
|
6025
6284
|
* Get full path for the store file
|
|
6026
6285
|
*/
|
|
6027
6286
|
getPath(projectId) {
|
|
6028
|
-
const basePath =
|
|
6287
|
+
const basePath = path16.join(path_manager_default.getGlobalProjectPath(projectId), "memory");
|
|
6029
6288
|
const subdir = this.getSubdirectory();
|
|
6030
6289
|
if (subdir) {
|
|
6031
|
-
return
|
|
6290
|
+
return path16.join(basePath, subdir, this.getFilename());
|
|
6032
6291
|
}
|
|
6033
|
-
return
|
|
6292
|
+
return path16.join(basePath, this.getFilename());
|
|
6034
6293
|
}
|
|
6035
6294
|
/**
|
|
6036
6295
|
* Load data from disk (with caching)
|
|
@@ -6042,7 +6301,7 @@ var init_memory_system = __esm({
|
|
|
6042
6301
|
}
|
|
6043
6302
|
const filePath = this.getPath(projectId);
|
|
6044
6303
|
try {
|
|
6045
|
-
const content = await
|
|
6304
|
+
const content = await fs17.readFile(filePath, "utf-8");
|
|
6046
6305
|
this._data = JSON.parse(content);
|
|
6047
6306
|
this.afterLoad(this._data);
|
|
6048
6307
|
} catch (error) {
|
|
@@ -6068,8 +6327,8 @@ var init_memory_system = __esm({
|
|
|
6068
6327
|
async save(projectId) {
|
|
6069
6328
|
if (!this._data) return;
|
|
6070
6329
|
const filePath = this.getPath(projectId);
|
|
6071
|
-
await
|
|
6072
|
-
await
|
|
6330
|
+
await fs17.mkdir(path16.dirname(filePath), { recursive: true });
|
|
6331
|
+
await fs17.writeFile(filePath, JSON.stringify(this._data, null, 2), "utf-8");
|
|
6073
6332
|
}
|
|
6074
6333
|
/**
|
|
6075
6334
|
* Get cached data without loading (may be null)
|
|
@@ -6135,11 +6394,11 @@ var init_memory_system = __esm({
|
|
|
6135
6394
|
const now = /* @__PURE__ */ new Date();
|
|
6136
6395
|
const yearMonth = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}`;
|
|
6137
6396
|
const day = getTodayKey();
|
|
6138
|
-
return
|
|
6397
|
+
return path16.join(path_manager_default.getGlobalProjectPath(projectId), "memory", "sessions", yearMonth, `${day}.jsonl`);
|
|
6139
6398
|
}
|
|
6140
6399
|
async appendHistory(projectId, entry) {
|
|
6141
6400
|
const sessionPath = this._getSessionPath(projectId);
|
|
6142
|
-
await ensureDir(
|
|
6401
|
+
await ensureDir(path16.dirname(sessionPath));
|
|
6143
6402
|
const logEntry = {
|
|
6144
6403
|
ts: getTimestamp(),
|
|
6145
6404
|
...entry,
|
|
@@ -6608,9 +6867,9 @@ Context: ${context}` : ""}`,
|
|
|
6608
6867
|
});
|
|
6609
6868
|
|
|
6610
6869
|
// core/agentic/ground-truth.ts
|
|
6611
|
-
import
|
|
6612
|
-
import
|
|
6613
|
-
import
|
|
6870
|
+
import fs18 from "fs/promises";
|
|
6871
|
+
import path17 from "path";
|
|
6872
|
+
import os7 from "os";
|
|
6614
6873
|
import { execSync as execSync2 } from "child_process";
|
|
6615
6874
|
function formatDuration2(ms) {
|
|
6616
6875
|
const hours = Math.floor(ms / (1e3 * 60 * 60));
|
|
@@ -6647,7 +6906,7 @@ async function verifyDone(context) {
|
|
|
6647
6906
|
const actual = {};
|
|
6648
6907
|
const nowPath = context.paths.now;
|
|
6649
6908
|
try {
|
|
6650
|
-
const nowContent = await
|
|
6909
|
+
const nowContent = await fs18.readFile(nowPath, "utf-8");
|
|
6651
6910
|
actual.nowExists = true;
|
|
6652
6911
|
actual.nowContent = nowContent.trim();
|
|
6653
6912
|
actual.nowLength = nowContent.length;
|
|
@@ -6671,7 +6930,7 @@ async function verifyDone(context) {
|
|
|
6671
6930
|
}
|
|
6672
6931
|
const nextPath = context.paths.next;
|
|
6673
6932
|
try {
|
|
6674
|
-
const nextContent = await
|
|
6933
|
+
const nextContent = await fs18.readFile(nextPath, "utf-8");
|
|
6675
6934
|
actual.nextExists = true;
|
|
6676
6935
|
const tasks = nextContent.match(/- \[ \]/g) || [];
|
|
6677
6936
|
actual.pendingTasks = tasks.length;
|
|
@@ -6681,7 +6940,7 @@ async function verifyDone(context) {
|
|
|
6681
6940
|
}
|
|
6682
6941
|
const metricsPath = context.paths.metrics;
|
|
6683
6942
|
try {
|
|
6684
|
-
await
|
|
6943
|
+
await fs18.access(path17.dirname(metricsPath), fs18.constants.W_OK);
|
|
6685
6944
|
actual.metricsWritable = true;
|
|
6686
6945
|
} catch {
|
|
6687
6946
|
actual.metricsWritable = false;
|
|
@@ -6712,9 +6971,9 @@ async function verifyShip(context) {
|
|
|
6712
6971
|
} catch {
|
|
6713
6972
|
actual.gitAvailable = false;
|
|
6714
6973
|
}
|
|
6715
|
-
const pkgPath =
|
|
6974
|
+
const pkgPath = path17.join(context.projectPath, "package.json");
|
|
6716
6975
|
try {
|
|
6717
|
-
const pkgContent = await
|
|
6976
|
+
const pkgContent = await fs18.readFile(pkgPath, "utf-8");
|
|
6718
6977
|
const pkg = JSON.parse(pkgContent);
|
|
6719
6978
|
actual.currentVersion = pkg.version;
|
|
6720
6979
|
actual.hasPackageJson = true;
|
|
@@ -6723,7 +6982,7 @@ async function verifyShip(context) {
|
|
|
6723
6982
|
}
|
|
6724
6983
|
const shippedPath = context.paths.shipped;
|
|
6725
6984
|
try {
|
|
6726
|
-
const shippedContent = await
|
|
6985
|
+
const shippedContent = await fs18.readFile(shippedPath, "utf-8");
|
|
6727
6986
|
actual.shippedExists = true;
|
|
6728
6987
|
const featureName = context.params.feature || context.params.description;
|
|
6729
6988
|
if (featureName) {
|
|
@@ -6739,7 +6998,7 @@ async function verifyShip(context) {
|
|
|
6739
6998
|
}
|
|
6740
6999
|
if (actual.hasPackageJson) {
|
|
6741
7000
|
try {
|
|
6742
|
-
const pkgContent = await
|
|
7001
|
+
const pkgContent = await fs18.readFile(pkgPath, "utf-8");
|
|
6743
7002
|
const pkg = JSON.parse(pkgContent);
|
|
6744
7003
|
actual.hasTestScript = !!pkg.scripts?.test;
|
|
6745
7004
|
} catch {
|
|
@@ -6759,7 +7018,7 @@ async function verifyFeature(context) {
|
|
|
6759
7018
|
const actual = {};
|
|
6760
7019
|
const nextPath = context.paths.next;
|
|
6761
7020
|
try {
|
|
6762
|
-
const nextContent = await
|
|
7021
|
+
const nextContent = await fs18.readFile(nextPath, "utf-8");
|
|
6763
7022
|
actual.nextExists = true;
|
|
6764
7023
|
const tasks = nextContent.match(/- \[[ x]\]/g) || [];
|
|
6765
7024
|
actual.taskCount = tasks.length;
|
|
@@ -6774,7 +7033,7 @@ async function verifyFeature(context) {
|
|
|
6774
7033
|
}
|
|
6775
7034
|
const roadmapPath = context.paths.roadmap;
|
|
6776
7035
|
try {
|
|
6777
|
-
const roadmapContent = await
|
|
7036
|
+
const roadmapContent = await fs18.readFile(roadmapPath, "utf-8");
|
|
6778
7037
|
actual.roadmapExists = true;
|
|
6779
7038
|
const featureName = context.params.description || context.params.feature;
|
|
6780
7039
|
if (featureName) {
|
|
@@ -6789,7 +7048,7 @@ async function verifyFeature(context) {
|
|
|
6789
7048
|
}
|
|
6790
7049
|
const nowPath = context.paths.now;
|
|
6791
7050
|
try {
|
|
6792
|
-
const nowContent = await
|
|
7051
|
+
const nowContent = await fs18.readFile(nowPath, "utf-8");
|
|
6793
7052
|
actual.hasActiveTask = nowContent.trim().length > 0 && !nowContent.includes("No current task");
|
|
6794
7053
|
if (actual.hasActiveTask) {
|
|
6795
7054
|
recommendations.push("Consider completing current task first with /p:done");
|
|
@@ -6810,7 +7069,7 @@ async function verifyNow(context) {
|
|
|
6810
7069
|
const actual = {};
|
|
6811
7070
|
const nowPath = context.paths.now;
|
|
6812
7071
|
try {
|
|
6813
|
-
const nowContent = await
|
|
7072
|
+
const nowContent = await fs18.readFile(nowPath, "utf-8");
|
|
6814
7073
|
actual.nowExists = true;
|
|
6815
7074
|
actual.nowContent = nowContent.trim();
|
|
6816
7075
|
const hasRealTask = nowContent.trim().length > 0 && !nowContent.includes("No current task") && !nowContent.match(/^#\s*NOW\s*$/m);
|
|
@@ -6826,7 +7085,7 @@ async function verifyNow(context) {
|
|
|
6826
7085
|
}
|
|
6827
7086
|
const nextPath = context.paths.next;
|
|
6828
7087
|
try {
|
|
6829
|
-
const nextContent = await
|
|
7088
|
+
const nextContent = await fs18.readFile(nextPath, "utf-8");
|
|
6830
7089
|
const pendingTasks = (nextContent.match(/- \[ \]/g) || []).length;
|
|
6831
7090
|
actual.pendingTasks = pendingTasks;
|
|
6832
7091
|
if (!context.params.task && pendingTasks > 0) {
|
|
@@ -6846,9 +7105,9 @@ async function verifyInit(context) {
|
|
|
6846
7105
|
const warnings = [];
|
|
6847
7106
|
const recommendations = [];
|
|
6848
7107
|
const actual = {};
|
|
6849
|
-
const configPath =
|
|
7108
|
+
const configPath = path17.join(context.projectPath, ".prjct/prjct.config.json");
|
|
6850
7109
|
try {
|
|
6851
|
-
const configContent = await
|
|
7110
|
+
const configContent = await fs18.readFile(configPath, "utf-8");
|
|
6852
7111
|
actual.alreadyInitialized = true;
|
|
6853
7112
|
actual.existingConfig = JSON.parse(configContent);
|
|
6854
7113
|
warnings.push("Project already initialized");
|
|
@@ -6856,13 +7115,13 @@ async function verifyInit(context) {
|
|
|
6856
7115
|
} catch {
|
|
6857
7116
|
actual.alreadyInitialized = false;
|
|
6858
7117
|
}
|
|
6859
|
-
const globalPath =
|
|
7118
|
+
const globalPath = path17.join(os7.homedir(), ".prjct-cli");
|
|
6860
7119
|
try {
|
|
6861
|
-
await
|
|
7120
|
+
await fs18.access(globalPath, fs18.constants.W_OK);
|
|
6862
7121
|
actual.globalPathWritable = true;
|
|
6863
7122
|
} catch {
|
|
6864
7123
|
try {
|
|
6865
|
-
await
|
|
7124
|
+
await fs18.mkdir(globalPath, { recursive: true });
|
|
6866
7125
|
actual.globalPathWritable = true;
|
|
6867
7126
|
actual.globalPathCreated = true;
|
|
6868
7127
|
} catch {
|
|
@@ -6882,9 +7141,9 @@ async function verifySync(context) {
|
|
|
6882
7141
|
const warnings = [];
|
|
6883
7142
|
const recommendations = [];
|
|
6884
7143
|
const actual = {};
|
|
6885
|
-
const configPath =
|
|
7144
|
+
const configPath = path17.join(context.projectPath, ".prjct/prjct.config.json");
|
|
6886
7145
|
try {
|
|
6887
|
-
const configContent = await
|
|
7146
|
+
const configContent = await fs18.readFile(configPath, "utf-8");
|
|
6888
7147
|
actual.hasConfig = true;
|
|
6889
7148
|
actual.config = JSON.parse(configContent);
|
|
6890
7149
|
} catch {
|
|
@@ -6894,9 +7153,9 @@ async function verifySync(context) {
|
|
|
6894
7153
|
return { verified: false, actual, warnings, recommendations };
|
|
6895
7154
|
}
|
|
6896
7155
|
const projectId = actual.config?.projectId;
|
|
6897
|
-
const globalProjectPath =
|
|
7156
|
+
const globalProjectPath = path17.join(os7.homedir(), ".prjct-cli/projects", projectId || "");
|
|
6898
7157
|
try {
|
|
6899
|
-
await
|
|
7158
|
+
await fs18.access(globalProjectPath);
|
|
6900
7159
|
actual.globalStorageExists = true;
|
|
6901
7160
|
} catch {
|
|
6902
7161
|
actual.globalStorageExists = false;
|
|
@@ -6918,7 +7177,7 @@ async function verifyAnalyze(context) {
|
|
|
6918
7177
|
actual.detectedFiles = [];
|
|
6919
7178
|
for (const file of files) {
|
|
6920
7179
|
try {
|
|
6921
|
-
await
|
|
7180
|
+
await fs18.access(path17.join(context.projectPath, file));
|
|
6922
7181
|
actual.detectedFiles.push(file);
|
|
6923
7182
|
} catch {
|
|
6924
7183
|
}
|
|
@@ -6931,7 +7190,7 @@ async function verifyAnalyze(context) {
|
|
|
6931
7190
|
actual.detectedSrcDirs = [];
|
|
6932
7191
|
for (const dir of srcDirs) {
|
|
6933
7192
|
try {
|
|
6934
|
-
const stat = await
|
|
7193
|
+
const stat = await fs18.stat(path17.join(context.projectPath, dir));
|
|
6935
7194
|
if (stat.isDirectory()) {
|
|
6936
7195
|
;
|
|
6937
7196
|
actual.detectedSrcDirs.push(dir);
|
|
@@ -6953,9 +7212,9 @@ async function verifySpec(context) {
|
|
|
6953
7212
|
const actual = {};
|
|
6954
7213
|
const specsPath = context.paths.specs;
|
|
6955
7214
|
try {
|
|
6956
|
-
await
|
|
7215
|
+
await fs18.access(specsPath);
|
|
6957
7216
|
actual.specsExists = true;
|
|
6958
|
-
const files = await
|
|
7217
|
+
const files = await fs18.readdir(specsPath);
|
|
6959
7218
|
actual.existingSpecs = files.filter((f) => f.endsWith(".md"));
|
|
6960
7219
|
actual.specCount = actual.existingSpecs.length;
|
|
6961
7220
|
} catch {
|
|
@@ -7486,150 +7745,31 @@ var init_plan_mode = __esm({
|
|
|
7486
7745
|
}
|
|
7487
7746
|
});
|
|
7488
7747
|
|
|
7489
|
-
// core/agentic/
|
|
7490
|
-
import
|
|
7491
|
-
import
|
|
7492
|
-
|
|
7493
|
-
|
|
7494
|
-
|
|
7495
|
-
|
|
7496
|
-
|
|
7497
|
-
|
|
7498
|
-
|
|
7499
|
-
|
|
7500
|
-
|
|
7501
|
-
|
|
7502
|
-
|
|
7503
|
-
|
|
7504
|
-
|
|
7505
|
-
|
|
7506
|
-
|
|
7507
|
-
|
|
7508
|
-
|
|
7509
|
-
|
|
7510
|
-
|
|
7511
|
-
|
|
7512
|
-
|
|
7513
|
-
|
|
7514
|
-
* Load all available agents from global storage
|
|
7515
|
-
*/
|
|
7516
|
-
async loadAvailableAgents() {
|
|
7517
|
-
if (!this.agentsPath) return [];
|
|
7518
|
-
try {
|
|
7519
|
-
const files = await fs18.readdir(this.agentsPath);
|
|
7520
|
-
const agents = [];
|
|
7521
|
-
for (const file of files) {
|
|
7522
|
-
if (file.endsWith(".md")) {
|
|
7523
|
-
const name = file.replace(".md", "");
|
|
7524
|
-
const content = await fs18.readFile(path17.join(this.agentsPath, file), "utf-8");
|
|
7525
|
-
agents.push({ name, content });
|
|
7526
|
-
}
|
|
7527
|
-
}
|
|
7528
|
-
return agents;
|
|
7529
|
-
} catch {
|
|
7530
|
-
return [];
|
|
7531
|
-
}
|
|
7532
|
-
}
|
|
7533
|
-
/**
|
|
7534
|
-
* Get list of available agent names
|
|
7535
|
-
*/
|
|
7536
|
-
async getAgentNames() {
|
|
7537
|
-
const agents = await this.loadAvailableAgents();
|
|
7538
|
-
return agents.map((a) => a.name);
|
|
7539
|
-
}
|
|
7540
|
-
/**
|
|
7541
|
-
* Load a specific agent by name from global storage
|
|
7542
|
-
*/
|
|
7543
|
-
async loadAgent(name) {
|
|
7544
|
-
if (!this.agentsPath) return null;
|
|
7545
|
-
try {
|
|
7546
|
-
const filePath = path17.join(this.agentsPath, `${name}.md`);
|
|
7547
|
-
const content = await fs18.readFile(filePath, "utf-8");
|
|
7548
|
-
return { name, content };
|
|
7549
|
-
} catch {
|
|
7550
|
-
return null;
|
|
7551
|
-
}
|
|
7552
|
-
}
|
|
7553
|
-
/**
|
|
7554
|
-
* Build context for Claude to decide agent assignment
|
|
7555
|
-
*/
|
|
7556
|
-
async buildAssignmentContext(task, projectPath) {
|
|
7557
|
-
const agents = await this.getAgentNames();
|
|
7558
|
-
return {
|
|
7559
|
-
task: typeof task === "string" ? task : task.description || "",
|
|
7560
|
-
availableAgents: agents,
|
|
7561
|
-
projectPath,
|
|
7562
|
-
projectId: this.projectId,
|
|
7563
|
-
// Claude reads this and decides via template
|
|
7564
|
-
_template: "templates/agent-assignment.md"
|
|
7565
|
-
};
|
|
7566
|
-
}
|
|
7567
|
-
/**
|
|
7568
|
-
* Load multiple agents by @ mention names
|
|
7569
|
-
* @example loadAgentsByMention(["frontend", "uxui"]) -> [Agent, Agent]
|
|
7570
|
-
*/
|
|
7571
|
-
async loadAgentsByMention(mentions) {
|
|
7572
|
-
const agents = [];
|
|
7573
|
-
for (const name of mentions) {
|
|
7574
|
-
const agent = await this.loadAgent(name);
|
|
7575
|
-
if (agent) {
|
|
7576
|
-
agents.push(agent);
|
|
7577
|
-
}
|
|
7578
|
-
}
|
|
7579
|
-
return agents;
|
|
7580
|
-
}
|
|
7581
|
-
/**
|
|
7582
|
-
* Log agent usage to JSONL file
|
|
7583
|
-
*/
|
|
7584
|
-
async logUsage(task, agent, _projectPath) {
|
|
7585
|
-
try {
|
|
7586
|
-
const logPath = path17.join(
|
|
7587
|
-
process.env.HOME || "",
|
|
7588
|
-
".prjct-cli",
|
|
7589
|
-
"projects",
|
|
7590
|
-
this.projectId || "",
|
|
7591
|
-
"agent-usage.jsonl"
|
|
7592
|
-
);
|
|
7593
|
-
const entry = JSON.stringify({
|
|
7594
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7595
|
-
task: typeof task === "string" ? task : task.description,
|
|
7596
|
-
agent: typeof agent === "string" ? agent : agent.name,
|
|
7597
|
-
projectId: this.projectId
|
|
7598
|
-
}) + "\n";
|
|
7599
|
-
await fs18.appendFile(logPath, entry);
|
|
7600
|
-
} catch {
|
|
7601
|
-
}
|
|
7602
|
-
}
|
|
7603
|
-
};
|
|
7604
|
-
agent_router_default = AgentRouter;
|
|
7605
|
-
}
|
|
7606
|
-
});
|
|
7607
|
-
|
|
7608
|
-
// core/agentic/command-executor.ts
|
|
7609
|
-
import fs19 from "fs";
|
|
7610
|
-
import path18 from "path";
|
|
7611
|
-
import os7 from "os";
|
|
7612
|
-
function signalStart(commandName) {
|
|
7613
|
-
try {
|
|
7614
|
-
const dir = path18.dirname(RUNNING_FILE);
|
|
7615
|
-
if (!fs19.existsSync(dir)) {
|
|
7616
|
-
fs19.mkdirSync(dir, { recursive: true });
|
|
7617
|
-
}
|
|
7618
|
-
fs19.writeFileSync(RUNNING_FILE, `/p:${commandName}`);
|
|
7619
|
-
} catch {
|
|
7620
|
-
}
|
|
7621
|
-
}
|
|
7622
|
-
function signalEnd() {
|
|
7623
|
-
try {
|
|
7624
|
-
if (fs19.existsSync(RUNNING_FILE)) {
|
|
7625
|
-
fs19.unlinkSync(RUNNING_FILE);
|
|
7626
|
-
}
|
|
7627
|
-
} catch {
|
|
7628
|
-
}
|
|
7629
|
-
}
|
|
7630
|
-
var RUNNING_FILE, CommandExecutor, commandExecutor, command_executor_default;
|
|
7631
|
-
var init_command_executor = __esm({
|
|
7632
|
-
"core/agentic/command-executor.ts"() {
|
|
7748
|
+
// core/agentic/command-executor.ts
|
|
7749
|
+
import fs19 from "fs";
|
|
7750
|
+
import path18 from "path";
|
|
7751
|
+
import os8 from "os";
|
|
7752
|
+
function signalStart(commandName) {
|
|
7753
|
+
try {
|
|
7754
|
+
const dir = path18.dirname(RUNNING_FILE);
|
|
7755
|
+
if (!fs19.existsSync(dir)) {
|
|
7756
|
+
fs19.mkdirSync(dir, { recursive: true });
|
|
7757
|
+
}
|
|
7758
|
+
fs19.writeFileSync(RUNNING_FILE, `/p:${commandName}`);
|
|
7759
|
+
} catch {
|
|
7760
|
+
}
|
|
7761
|
+
}
|
|
7762
|
+
function signalEnd() {
|
|
7763
|
+
try {
|
|
7764
|
+
if (fs19.existsSync(RUNNING_FILE)) {
|
|
7765
|
+
fs19.unlinkSync(RUNNING_FILE);
|
|
7766
|
+
}
|
|
7767
|
+
} catch {
|
|
7768
|
+
}
|
|
7769
|
+
}
|
|
7770
|
+
var RUNNING_FILE, CommandExecutor, commandExecutor, command_executor_default;
|
|
7771
|
+
var init_command_executor = __esm({
|
|
7772
|
+
"core/agentic/command-executor.ts"() {
|
|
7633
7773
|
"use strict";
|
|
7634
7774
|
init_template_loader();
|
|
7635
7775
|
init_context_builder();
|
|
@@ -7640,8 +7780,7 @@ var init_command_executor = __esm({
|
|
|
7640
7780
|
init_memory_system();
|
|
7641
7781
|
init_ground_truth();
|
|
7642
7782
|
init_plan_mode();
|
|
7643
|
-
|
|
7644
|
-
RUNNING_FILE = path18.join(os7.homedir(), ".prjct-cli", ".running");
|
|
7783
|
+
RUNNING_FILE = path18.join(os8.homedir(), ".prjct-cli", ".running");
|
|
7645
7784
|
__name(signalStart, "signalStart");
|
|
7646
7785
|
__name(signalEnd, "signalEnd");
|
|
7647
7786
|
CommandExecutor = class {
|
|
@@ -7678,14 +7817,6 @@ var init_command_executor = __esm({
|
|
|
7678
7817
|
};
|
|
7679
7818
|
}
|
|
7680
7819
|
try {
|
|
7681
|
-
const taskInput = params.task || params.description || "";
|
|
7682
|
-
const { prjctAgents, claudeSubagents, cleanInput } = prompt_builder_default.parseAgentMentions(taskInput);
|
|
7683
|
-
if (prjctAgents.length > 0 || claudeSubagents.length > 0) {
|
|
7684
|
-
if (params.task) params.task = cleanInput;
|
|
7685
|
-
if (params.description) params.description = cleanInput;
|
|
7686
|
-
params._mentionedAgents = prjctAgents;
|
|
7687
|
-
params._claudeSubagents = claudeSubagents;
|
|
7688
|
-
}
|
|
7689
7820
|
const template = await template_loader_default.load(commandName);
|
|
7690
7821
|
const metadataContext = await context_builder_default.build(projectPath, params);
|
|
7691
7822
|
const requiresPlanning = plan_mode_default.requiresPlanning(commandName);
|
|
@@ -7725,7 +7856,7 @@ var init_command_executor = __esm({
|
|
|
7725
7856
|
let context = metadataContext;
|
|
7726
7857
|
context = {
|
|
7727
7858
|
...context,
|
|
7728
|
-
agentsPath: path18.join(
|
|
7859
|
+
agentsPath: path18.join(os8.homedir(), ".prjct-cli", "projects", metadataContext.projectId || "", "agents"),
|
|
7729
7860
|
agentRoutingPath: path18.join(__dirname, "..", "..", "templates", "agentic", "agent-routing.md"),
|
|
7730
7861
|
agenticDelegation: true
|
|
7731
7862
|
};
|
|
@@ -7748,50 +7879,23 @@ var init_command_executor = __esm({
|
|
|
7748
7879
|
5
|
|
7749
7880
|
);
|
|
7750
7881
|
}
|
|
7751
|
-
let primaryAgent = null;
|
|
7752
|
-
if (prjctAgents.length > 0) {
|
|
7753
|
-
const agentRouter = new agent_router_default();
|
|
7754
|
-
await agentRouter.initialize(projectPath);
|
|
7755
|
-
const loadedAgents = await agentRouter.loadAgentsByMention(prjctAgents);
|
|
7756
|
-
if (loadedAgents.length > 0) {
|
|
7757
|
-
primaryAgent = {
|
|
7758
|
-
name: loadedAgents[0].name,
|
|
7759
|
-
content: loadedAgents[0].content,
|
|
7760
|
-
role: void 0,
|
|
7761
|
-
skills: []
|
|
7762
|
-
};
|
|
7763
|
-
console.log(`\u{1F916} Loading agents: ${loadedAgents.map((a) => `@${a.name}`).join(", ")}`);
|
|
7764
|
-
}
|
|
7765
|
-
}
|
|
7766
7882
|
const planInfo = {
|
|
7767
7883
|
isPlanning: requiresPlanning || isInPlanningMode,
|
|
7768
7884
|
requiresApproval: isDestructive && !params.approved,
|
|
7769
7885
|
active: activePlan,
|
|
7770
7886
|
allowedTools: plan_mode_default.getAllowedTools(isInPlanningMode, template.frontmatter["allowed-tools"] || [])
|
|
7771
7887
|
};
|
|
7772
|
-
|
|
7888
|
+
const prompt = prompt_builder_default.build(
|
|
7773
7889
|
template,
|
|
7774
7890
|
context,
|
|
7775
7891
|
state,
|
|
7776
|
-
|
|
7892
|
+
null,
|
|
7777
7893
|
learnedPatterns,
|
|
7778
7894
|
null,
|
|
7779
7895
|
relevantMemories,
|
|
7780
7896
|
planInfo
|
|
7781
7897
|
);
|
|
7782
|
-
|
|
7783
|
-
const subagentInstructions = prompt_builder_default.buildSubagentInstructions(claudeSubagents);
|
|
7784
|
-
prompt = prompt + subagentInstructions;
|
|
7785
|
-
console.log(`\u{1F527} Claude subagents requested: ${claudeSubagents.map((s) => `@${s}`).join(", ")}`);
|
|
7786
|
-
}
|
|
7787
|
-
const toolPermissions = template.frontmatter["tool-permissions"];
|
|
7788
|
-
if (toolPermissions) {
|
|
7789
|
-
const permissionsSection = prompt_builder_default.buildToolPermissions(toolPermissions);
|
|
7790
|
-
prompt = prompt + permissionsSection;
|
|
7791
|
-
}
|
|
7792
|
-
if (!primaryAgent) {
|
|
7793
|
-
console.log(`\u{1F916} Agentic delegation enabled - Claude will assign agent via Task tool`);
|
|
7794
|
-
}
|
|
7898
|
+
console.log(`\u{1F916} Agentic delegation enabled - Claude will assign agent via Task tool`);
|
|
7795
7899
|
loop_detector_default.recordSuccess(commandName, loopContext);
|
|
7796
7900
|
this.signalEnd();
|
|
7797
7901
|
return {
|
|
@@ -7917,7 +8021,7 @@ var init_command_executor = __esm({
|
|
|
7917
8021
|
import https from "https";
|
|
7918
8022
|
import fs20 from "fs";
|
|
7919
8023
|
import path19 from "path";
|
|
7920
|
-
import
|
|
8024
|
+
import os9 from "os";
|
|
7921
8025
|
import chalk from "chalk";
|
|
7922
8026
|
var UpdateChecker, update_checker_default;
|
|
7923
8027
|
var init_update_checker = __esm({
|
|
@@ -7933,7 +8037,7 @@ var init_update_checker = __esm({
|
|
|
7933
8037
|
checkInterval;
|
|
7934
8038
|
constructor() {
|
|
7935
8039
|
this.packageName = "prjct-cli";
|
|
7936
|
-
this.cacheDir = path19.join(
|
|
8040
|
+
this.cacheDir = path19.join(os9.homedir(), ".prjct-cli", "config");
|
|
7937
8041
|
this.cacheFile = path19.join(this.cacheDir, "update-cache.json");
|
|
7938
8042
|
this.checkInterval = 24 * 60 * 60 * 1e3;
|
|
7939
8043
|
}
|
|
@@ -8311,6 +8415,111 @@ var init_agent_detector = __esm({
|
|
|
8311
8415
|
}
|
|
8312
8416
|
});
|
|
8313
8417
|
|
|
8418
|
+
// core/agentic/agent-router.ts
|
|
8419
|
+
import fs22 from "fs/promises";
|
|
8420
|
+
import path21 from "path";
|
|
8421
|
+
var AgentRouter, agent_router_default;
|
|
8422
|
+
var init_agent_router = __esm({
|
|
8423
|
+
"core/agentic/agent-router.ts"() {
|
|
8424
|
+
"use strict";
|
|
8425
|
+
init_config_manager();
|
|
8426
|
+
init_path_manager();
|
|
8427
|
+
AgentRouter = class {
|
|
8428
|
+
static {
|
|
8429
|
+
__name(this, "AgentRouter");
|
|
8430
|
+
}
|
|
8431
|
+
projectId = null;
|
|
8432
|
+
projectPath = null;
|
|
8433
|
+
agentsPath = null;
|
|
8434
|
+
/**
|
|
8435
|
+
* Initialize router with project context
|
|
8436
|
+
*/
|
|
8437
|
+
async initialize(projectPath) {
|
|
8438
|
+
this.projectId = await config_manager_default.getProjectId(projectPath);
|
|
8439
|
+
this.projectPath = projectPath;
|
|
8440
|
+
this.agentsPath = path_manager_default.getFilePath(this.projectId, "agents", "");
|
|
8441
|
+
}
|
|
8442
|
+
/**
|
|
8443
|
+
* Load all available agents from global storage
|
|
8444
|
+
*/
|
|
8445
|
+
async loadAvailableAgents() {
|
|
8446
|
+
if (!this.agentsPath) return [];
|
|
8447
|
+
try {
|
|
8448
|
+
const files = await fs22.readdir(this.agentsPath);
|
|
8449
|
+
const agents = [];
|
|
8450
|
+
for (const file of files) {
|
|
8451
|
+
if (file.endsWith(".md")) {
|
|
8452
|
+
const name = file.replace(".md", "");
|
|
8453
|
+
const content = await fs22.readFile(path21.join(this.agentsPath, file), "utf-8");
|
|
8454
|
+
agents.push({ name, content });
|
|
8455
|
+
}
|
|
8456
|
+
}
|
|
8457
|
+
return agents;
|
|
8458
|
+
} catch {
|
|
8459
|
+
return [];
|
|
8460
|
+
}
|
|
8461
|
+
}
|
|
8462
|
+
/**
|
|
8463
|
+
* Get list of available agent names
|
|
8464
|
+
*/
|
|
8465
|
+
async getAgentNames() {
|
|
8466
|
+
const agents = await this.loadAvailableAgents();
|
|
8467
|
+
return agents.map((a) => a.name);
|
|
8468
|
+
}
|
|
8469
|
+
/**
|
|
8470
|
+
* Load a specific agent by name from global storage
|
|
8471
|
+
*/
|
|
8472
|
+
async loadAgent(name) {
|
|
8473
|
+
if (!this.agentsPath) return null;
|
|
8474
|
+
try {
|
|
8475
|
+
const filePath = path21.join(this.agentsPath, `${name}.md`);
|
|
8476
|
+
const content = await fs22.readFile(filePath, "utf-8");
|
|
8477
|
+
return { name, content };
|
|
8478
|
+
} catch {
|
|
8479
|
+
return null;
|
|
8480
|
+
}
|
|
8481
|
+
}
|
|
8482
|
+
/**
|
|
8483
|
+
* Build context for Claude to decide agent assignment
|
|
8484
|
+
*/
|
|
8485
|
+
async buildAssignmentContext(task, projectPath) {
|
|
8486
|
+
const agents = await this.getAgentNames();
|
|
8487
|
+
return {
|
|
8488
|
+
task: typeof task === "string" ? task : task.description || "",
|
|
8489
|
+
availableAgents: agents,
|
|
8490
|
+
projectPath,
|
|
8491
|
+
projectId: this.projectId,
|
|
8492
|
+
// Claude reads this and decides via template
|
|
8493
|
+
_template: "templates/agent-assignment.md"
|
|
8494
|
+
};
|
|
8495
|
+
}
|
|
8496
|
+
/**
|
|
8497
|
+
* Log agent usage to JSONL file
|
|
8498
|
+
*/
|
|
8499
|
+
async logUsage(task, agent, _projectPath) {
|
|
8500
|
+
try {
|
|
8501
|
+
const logPath = path21.join(
|
|
8502
|
+
process.env.HOME || "",
|
|
8503
|
+
".prjct-cli",
|
|
8504
|
+
"projects",
|
|
8505
|
+
this.projectId || "",
|
|
8506
|
+
"agent-usage.jsonl"
|
|
8507
|
+
);
|
|
8508
|
+
const entry = JSON.stringify({
|
|
8509
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8510
|
+
task: typeof task === "string" ? task : task.description,
|
|
8511
|
+
agent: typeof agent === "string" ? agent : agent.name,
|
|
8512
|
+
projectId: this.projectId
|
|
8513
|
+
}) + "\n";
|
|
8514
|
+
await fs22.appendFile(logPath, entry);
|
|
8515
|
+
} catch {
|
|
8516
|
+
}
|
|
8517
|
+
}
|
|
8518
|
+
};
|
|
8519
|
+
agent_router_default = AgentRouter;
|
|
8520
|
+
}
|
|
8521
|
+
});
|
|
8522
|
+
|
|
8314
8523
|
// import("../infrastructure/**/*-agent") in core/services/agent-service.ts
|
|
8315
8524
|
var globImport_infrastructure_agent;
|
|
8316
8525
|
var init_ = __esm({
|
|
@@ -8453,8 +8662,8 @@ var init_agent_service = __esm({
|
|
|
8453
8662
|
});
|
|
8454
8663
|
|
|
8455
8664
|
// core/domain/analyzer.ts
|
|
8456
|
-
import
|
|
8457
|
-
import
|
|
8665
|
+
import fs23 from "fs/promises";
|
|
8666
|
+
import path22 from "path";
|
|
8458
8667
|
import { promisify as promisify3 } from "util";
|
|
8459
8668
|
import { exec as execCallback2 } from "child_process";
|
|
8460
8669
|
var exec3, CodebaseAnalyzer, analyzer, analyzer_default2;
|
|
@@ -8478,8 +8687,8 @@ var init_analyzer2 = __esm({
|
|
|
8478
8687
|
*/
|
|
8479
8688
|
async readPackageJson() {
|
|
8480
8689
|
try {
|
|
8481
|
-
const packagePath =
|
|
8482
|
-
const content = await
|
|
8690
|
+
const packagePath = path22.join(this.projectPath, "package.json");
|
|
8691
|
+
const content = await fs23.readFile(packagePath, "utf-8");
|
|
8483
8692
|
return JSON.parse(content);
|
|
8484
8693
|
} catch {
|
|
8485
8694
|
return null;
|
|
@@ -8490,8 +8699,8 @@ var init_analyzer2 = __esm({
|
|
|
8490
8699
|
*/
|
|
8491
8700
|
async readCargoToml() {
|
|
8492
8701
|
try {
|
|
8493
|
-
const cargoPath =
|
|
8494
|
-
return await
|
|
8702
|
+
const cargoPath = path22.join(this.projectPath, "Cargo.toml");
|
|
8703
|
+
return await fs23.readFile(cargoPath, "utf-8");
|
|
8495
8704
|
} catch {
|
|
8496
8705
|
return null;
|
|
8497
8706
|
}
|
|
@@ -8501,8 +8710,8 @@ var init_analyzer2 = __esm({
|
|
|
8501
8710
|
*/
|
|
8502
8711
|
async readRequirements() {
|
|
8503
8712
|
try {
|
|
8504
|
-
const reqPath =
|
|
8505
|
-
return await
|
|
8713
|
+
const reqPath = path22.join(this.projectPath, "requirements.txt");
|
|
8714
|
+
return await fs23.readFile(reqPath, "utf-8");
|
|
8506
8715
|
} catch {
|
|
8507
8716
|
return null;
|
|
8508
8717
|
}
|
|
@@ -8512,8 +8721,8 @@ var init_analyzer2 = __esm({
|
|
|
8512
8721
|
*/
|
|
8513
8722
|
async readGoMod() {
|
|
8514
8723
|
try {
|
|
8515
|
-
const goModPath =
|
|
8516
|
-
return await
|
|
8724
|
+
const goModPath = path22.join(this.projectPath, "go.mod");
|
|
8725
|
+
return await fs23.readFile(goModPath, "utf-8");
|
|
8517
8726
|
} catch {
|
|
8518
8727
|
return null;
|
|
8519
8728
|
}
|
|
@@ -8523,8 +8732,8 @@ var init_analyzer2 = __esm({
|
|
|
8523
8732
|
*/
|
|
8524
8733
|
async readGemfile() {
|
|
8525
8734
|
try {
|
|
8526
|
-
const gemfilePath =
|
|
8527
|
-
return await
|
|
8735
|
+
const gemfilePath = path22.join(this.projectPath, "Gemfile");
|
|
8736
|
+
return await fs23.readFile(gemfilePath, "utf-8");
|
|
8528
8737
|
} catch {
|
|
8529
8738
|
return null;
|
|
8530
8739
|
}
|
|
@@ -8534,8 +8743,8 @@ var init_analyzer2 = __esm({
|
|
|
8534
8743
|
*/
|
|
8535
8744
|
async readMixExs() {
|
|
8536
8745
|
try {
|
|
8537
|
-
const mixPath =
|
|
8538
|
-
return await
|
|
8746
|
+
const mixPath = path22.join(this.projectPath, "mix.exs");
|
|
8747
|
+
return await fs23.readFile(mixPath, "utf-8");
|
|
8539
8748
|
} catch {
|
|
8540
8749
|
return null;
|
|
8541
8750
|
}
|
|
@@ -8545,8 +8754,8 @@ var init_analyzer2 = __esm({
|
|
|
8545
8754
|
*/
|
|
8546
8755
|
async readPomXml() {
|
|
8547
8756
|
try {
|
|
8548
|
-
const pomPath =
|
|
8549
|
-
return await
|
|
8757
|
+
const pomPath = path22.join(this.projectPath, "pom.xml");
|
|
8758
|
+
return await fs23.readFile(pomPath, "utf-8");
|
|
8550
8759
|
} catch {
|
|
8551
8760
|
return null;
|
|
8552
8761
|
}
|
|
@@ -8556,8 +8765,8 @@ var init_analyzer2 = __esm({
|
|
|
8556
8765
|
*/
|
|
8557
8766
|
async readComposerJson() {
|
|
8558
8767
|
try {
|
|
8559
|
-
const composerPath =
|
|
8560
|
-
const content = await
|
|
8768
|
+
const composerPath = path22.join(this.projectPath, "composer.json");
|
|
8769
|
+
const content = await fs23.readFile(composerPath, "utf-8");
|
|
8561
8770
|
return JSON.parse(content);
|
|
8562
8771
|
} catch {
|
|
8563
8772
|
return null;
|
|
@@ -8568,8 +8777,8 @@ var init_analyzer2 = __esm({
|
|
|
8568
8777
|
*/
|
|
8569
8778
|
async readPyprojectToml() {
|
|
8570
8779
|
try {
|
|
8571
|
-
const pyprojectPath =
|
|
8572
|
-
return await
|
|
8780
|
+
const pyprojectPath = path22.join(this.projectPath, "pyproject.toml");
|
|
8781
|
+
return await fs23.readFile(pyprojectPath, "utf-8");
|
|
8573
8782
|
} catch {
|
|
8574
8783
|
return null;
|
|
8575
8784
|
}
|
|
@@ -8602,7 +8811,7 @@ var init_analyzer2 = __esm({
|
|
|
8602
8811
|
*/
|
|
8603
8812
|
async listConfigFiles() {
|
|
8604
8813
|
try {
|
|
8605
|
-
const entries = await
|
|
8814
|
+
const entries = await fs23.readdir(this.projectPath);
|
|
8606
8815
|
const configPatterns = [
|
|
8607
8816
|
/^package\.json$/,
|
|
8608
8817
|
/^Cargo\.toml$/,
|
|
@@ -8629,7 +8838,7 @@ var init_analyzer2 = __esm({
|
|
|
8629
8838
|
*/
|
|
8630
8839
|
async listDirectories() {
|
|
8631
8840
|
try {
|
|
8632
|
-
const entries = await
|
|
8841
|
+
const entries = await fs23.readdir(this.projectPath, { withFileTypes: true });
|
|
8633
8842
|
return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).filter((name) => !name.startsWith(".") && name !== "node_modules");
|
|
8634
8843
|
} catch {
|
|
8635
8844
|
return [];
|
|
@@ -8694,7 +8903,7 @@ var init_analyzer2 = __esm({
|
|
|
8694
8903
|
*/
|
|
8695
8904
|
async fileExists(filename) {
|
|
8696
8905
|
try {
|
|
8697
|
-
await
|
|
8906
|
+
await fs23.access(path22.join(this.projectPath, filename));
|
|
8698
8907
|
return true;
|
|
8699
8908
|
} catch {
|
|
8700
8909
|
return false;
|
|
@@ -8705,8 +8914,8 @@ var init_analyzer2 = __esm({
|
|
|
8705
8914
|
*/
|
|
8706
8915
|
async readFile(relativePath) {
|
|
8707
8916
|
try {
|
|
8708
|
-
const fullPath =
|
|
8709
|
-
return await
|
|
8917
|
+
const fullPath = path22.join(this.projectPath, relativePath);
|
|
8918
|
+
return await fs23.readFile(fullPath, "utf-8");
|
|
8710
8919
|
} catch {
|
|
8711
8920
|
return null;
|
|
8712
8921
|
}
|
|
@@ -8732,16 +8941,16 @@ var init_analyzer2 = __esm({
|
|
|
8732
8941
|
});
|
|
8733
8942
|
|
|
8734
8943
|
// core/context/generator.ts
|
|
8735
|
-
import
|
|
8736
|
-
import
|
|
8737
|
-
import
|
|
8944
|
+
import fs24 from "fs/promises";
|
|
8945
|
+
import path23 from "path";
|
|
8946
|
+
import os10 from "os";
|
|
8738
8947
|
import { exec as exec4 } from "child_process";
|
|
8739
8948
|
import { promisify as promisify4 } from "util";
|
|
8740
8949
|
async function generateContext(projectId, repoPath) {
|
|
8741
|
-
const globalPath =
|
|
8742
|
-
const contextPath =
|
|
8950
|
+
const globalPath = path23.join(os10.homedir(), ".prjct-cli/projects", projectId);
|
|
8951
|
+
const contextPath = path23.join(globalPath, "context");
|
|
8743
8952
|
const storage = getStorage(projectId);
|
|
8744
|
-
await
|
|
8953
|
+
await fs24.mkdir(contextPath, { recursive: true });
|
|
8745
8954
|
const project = await storage.read(["project"]) || {};
|
|
8746
8955
|
const taskPaths = await storage.list(["task"]);
|
|
8747
8956
|
const featurePaths = await storage.list(["feature"]);
|
|
@@ -8807,8 +9016,8 @@ async function getPackageData(repoPath) {
|
|
|
8807
9016
|
scripts: {}
|
|
8808
9017
|
};
|
|
8809
9018
|
try {
|
|
8810
|
-
const pkgPath =
|
|
8811
|
-
const pkg = JSON.parse(await
|
|
9019
|
+
const pkgPath = path23.join(repoPath, "package.json");
|
|
9020
|
+
const pkg = JSON.parse(await fs24.readFile(pkgPath, "utf-8"));
|
|
8812
9021
|
data.dependencies = pkg.dependencies || {};
|
|
8813
9022
|
data.devDependencies = pkg.devDependencies || {};
|
|
8814
9023
|
data.scripts = pkg.scripts || {};
|
|
@@ -8817,7 +9026,7 @@ async function getPackageData(repoPath) {
|
|
|
8817
9026
|
return data;
|
|
8818
9027
|
}
|
|
8819
9028
|
async function generateClaudeMd(contextPath, projectId, project, tasks, features, ideas, agents, gitData, pkgData, repoPath) {
|
|
8820
|
-
const projectName = project.name ||
|
|
9029
|
+
const projectName = project.name || path23.basename(repoPath);
|
|
8821
9030
|
const currentTask = tasks.find((t) => t.status === "in_progress");
|
|
8822
9031
|
const pendingTasks = tasks.filter((t) => t.status === "pending");
|
|
8823
9032
|
const activeFeatures = features.filter((f) => f.status === "in_progress" || f.status === "active");
|
|
@@ -8892,7 +9101,7 @@ ${agents.length > 0 ? agents.map((a) => `- **${a.name}**: ${a.role || "Specialis
|
|
|
8892
9101
|
\u2514\u2500\u2500 pending.json
|
|
8893
9102
|
\`\`\`
|
|
8894
9103
|
`;
|
|
8895
|
-
await
|
|
9104
|
+
await fs24.writeFile(path23.join(contextPath, "CLAUDE.md"), content, "utf-8");
|
|
8896
9105
|
}
|
|
8897
9106
|
async function generateNowMd(contextPath, tasks) {
|
|
8898
9107
|
const currentTask = tasks.find((t) => t.status === "in_progress");
|
|
@@ -8907,7 +9116,7 @@ async function generateNowMd(contextPath, tasks) {
|
|
|
8907
9116
|
|
|
8908
9117
|
_No active task. Use /p:now to start._
|
|
8909
9118
|
`;
|
|
8910
|
-
await
|
|
9119
|
+
await fs24.writeFile(path23.join(contextPath, "now.md"), content, "utf-8");
|
|
8911
9120
|
}
|
|
8912
9121
|
async function generateQueueMd(contextPath, tasks) {
|
|
8913
9122
|
const pendingTasks = tasks.filter((t) => t.status === "pending");
|
|
@@ -8915,7 +9124,7 @@ async function generateQueueMd(contextPath, tasks) {
|
|
|
8915
9124
|
|
|
8916
9125
|
${pendingTasks.length > 0 ? pendingTasks.map((t, i) => `${i + 1}. ${t.description}${t.priority ? ` [${t.priority}]` : ""}`).join("\n") : "_Empty queue. Use /p:next to add tasks._"}
|
|
8917
9126
|
`;
|
|
8918
|
-
await
|
|
9127
|
+
await fs24.writeFile(path23.join(contextPath, "queue.md"), content, "utf-8");
|
|
8919
9128
|
}
|
|
8920
9129
|
async function generateSummaryMd(contextPath, project, gitData, pkgData) {
|
|
8921
9130
|
const content = `# PROJECT SUMMARY
|
|
@@ -8935,7 +9144,7 @@ async function generateSummaryMd(contextPath, project, gitData, pkgData) {
|
|
|
8935
9144
|
- Production: ${Object.keys(pkgData.dependencies).length}
|
|
8936
9145
|
- Dev: ${Object.keys(pkgData.devDependencies).length}
|
|
8937
9146
|
`;
|
|
8938
|
-
await
|
|
9147
|
+
await fs24.writeFile(path23.join(contextPath, "summary.md"), content, "utf-8");
|
|
8939
9148
|
}
|
|
8940
9149
|
var execAsync2;
|
|
8941
9150
|
var init_generator = __esm({
|
|
@@ -8958,7 +9167,7 @@ var analysis_exports = {};
|
|
|
8958
9167
|
__export(analysis_exports, {
|
|
8959
9168
|
AnalysisCommands: () => AnalysisCommands
|
|
8960
9169
|
});
|
|
8961
|
-
import
|
|
9170
|
+
import path24 from "path";
|
|
8962
9171
|
var AnalysisCommands;
|
|
8963
9172
|
var init_analysis2 = __esm({
|
|
8964
9173
|
"core/commands/analysis.ts"() {
|
|
@@ -9038,7 +9247,7 @@ var init_analysis2 = __esm({
|
|
|
9038
9247
|
lines.push("# Repository Analysis\n");
|
|
9039
9248
|
lines.push(`Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
9040
9249
|
`);
|
|
9041
|
-
const projectName =
|
|
9250
|
+
const projectName = path24.basename(projectPath);
|
|
9042
9251
|
lines.push(`## Project: ${projectName}
|
|
9043
9252
|
`);
|
|
9044
9253
|
lines.push("## Stack Detected\n");
|
|
@@ -9162,7 +9371,7 @@ var planning_exports = {};
|
|
|
9162
9371
|
__export(planning_exports, {
|
|
9163
9372
|
PlanningCommands: () => PlanningCommands
|
|
9164
9373
|
});
|
|
9165
|
-
import
|
|
9374
|
+
import path25 from "path";
|
|
9166
9375
|
async function getAnalysisCommands() {
|
|
9167
9376
|
if (!_analysisCommands) {
|
|
9168
9377
|
const { AnalysisCommands: AnalysisCommands2 } = await Promise.resolve().then(() => (init_analysis2(), analysis_exports));
|
|
@@ -9227,7 +9436,7 @@ var init_planning = __esm({
|
|
|
9227
9436
|
}, null, 2)
|
|
9228
9437
|
};
|
|
9229
9438
|
for (const [filePath, content] of Object.entries(baseFiles)) {
|
|
9230
|
-
await tool_registry_default.get("Write")(
|
|
9439
|
+
await tool_registry_default.get("Write")(path25.join(globalPath, filePath), content);
|
|
9231
9440
|
}
|
|
9232
9441
|
const isEmpty = await this._detectEmptyDirectory(projectPath);
|
|
9233
9442
|
const hasCode = await this._detectExistingCode(projectPath);
|
|
@@ -9248,7 +9457,7 @@ var init_planning = __esm({
|
|
|
9248
9457
|
return { success: true, mode: "blank_no_idea", projectId };
|
|
9249
9458
|
}
|
|
9250
9459
|
output_default.spin("architect mode...");
|
|
9251
|
-
const sessionPath =
|
|
9460
|
+
const sessionPath = path25.join(globalPath, "planning", "architect-session.md");
|
|
9252
9461
|
const sessionContent = `# Architect Session
|
|
9253
9462
|
|
|
9254
9463
|
## Idea
|
|
@@ -9390,7 +9599,7 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
9390
9599
|
if (!initResult.success) return initResult;
|
|
9391
9600
|
console.log("\u{1F3D7}\uFE0F Architect Mode - Code Generation\n");
|
|
9392
9601
|
const globalPath = await this.getGlobalProjectPath(projectPath);
|
|
9393
|
-
const planPath =
|
|
9602
|
+
const planPath = path25.join(globalPath, "planning", "architect-session.md");
|
|
9394
9603
|
let planContent;
|
|
9395
9604
|
try {
|
|
9396
9605
|
planContent = await file_helper_exports.readFile(planPath);
|
|
@@ -9464,7 +9673,7 @@ ${steps}`);
|
|
|
9464
9673
|
if (isComplex) {
|
|
9465
9674
|
output_default.spin("analyzing idea...");
|
|
9466
9675
|
const globalPath = path_manager_default.getGlobalProjectPath(projectId);
|
|
9467
|
-
const sessionPath =
|
|
9676
|
+
const sessionPath = path25.join(globalPath, "planning", "architect-session.md");
|
|
9468
9677
|
const sessionContent = `# Architect Session
|
|
9469
9678
|
|
|
9470
9679
|
## Idea
|
|
@@ -9519,10 +9728,10 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
9519
9728
|
if (!featureName) {
|
|
9520
9729
|
output_default.spin("loading specs...");
|
|
9521
9730
|
const globalPath2 = path_manager_default.getGlobalProjectPath(projectId);
|
|
9522
|
-
const specsPath2 =
|
|
9731
|
+
const specsPath2 = path25.join(globalPath2, "planning", "specs");
|
|
9523
9732
|
try {
|
|
9524
|
-
const
|
|
9525
|
-
const files = await
|
|
9733
|
+
const fs26 = await import("fs/promises");
|
|
9734
|
+
const files = await fs26.readdir(specsPath2);
|
|
9526
9735
|
const specs = files.filter((f) => f.endsWith(".md") && f !== ".gitkeep");
|
|
9527
9736
|
if (specs.length === 0) {
|
|
9528
9737
|
output_default.warn("no specs yet");
|
|
@@ -9544,10 +9753,10 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
9544
9753
|
}
|
|
9545
9754
|
output_default.spin("creating spec...");
|
|
9546
9755
|
const globalPath = path_manager_default.getGlobalProjectPath(projectId);
|
|
9547
|
-
const specsPath =
|
|
9756
|
+
const specsPath = path25.join(globalPath, "planning", "specs");
|
|
9548
9757
|
await file_helper_exports.ensureDir(specsPath);
|
|
9549
9758
|
const slug = featureName.toLowerCase().replace(/\s+/g, "-");
|
|
9550
|
-
const specFile =
|
|
9759
|
+
const specFile = path25.join(specsPath, `${slug}.md`);
|
|
9551
9760
|
const specContent = `# Specification: ${featureName}
|
|
9552
9761
|
|
|
9553
9762
|
## Overview
|
|
@@ -10159,18 +10368,18 @@ var init_workflow = __esm({
|
|
|
10159
10368
|
});
|
|
10160
10369
|
|
|
10161
10370
|
// core/utils/project-commands.ts
|
|
10162
|
-
import
|
|
10371
|
+
import path26 from "path";
|
|
10163
10372
|
async function detectPackageManager(projectPath, pkg) {
|
|
10164
10373
|
const declared = pkg?.packageManager?.trim().toLowerCase();
|
|
10165
10374
|
if (declared?.startsWith("pnpm@")) return "pnpm";
|
|
10166
10375
|
if (declared?.startsWith("yarn@")) return "yarn";
|
|
10167
10376
|
if (declared?.startsWith("bun@")) return "bun";
|
|
10168
10377
|
if (declared?.startsWith("npm@")) return "npm";
|
|
10169
|
-
if (await fileExists(
|
|
10170
|
-
if (await fileExists(
|
|
10171
|
-
if (await fileExists(
|
|
10172
|
-
if (await fileExists(
|
|
10173
|
-
if (await fileExists(
|
|
10378
|
+
if (await fileExists(path26.join(projectPath, "pnpm-lock.yaml"))) return "pnpm";
|
|
10379
|
+
if (await fileExists(path26.join(projectPath, "yarn.lock"))) return "yarn";
|
|
10380
|
+
if (await fileExists(path26.join(projectPath, "bun.lockb"))) return "bun";
|
|
10381
|
+
if (await fileExists(path26.join(projectPath, "bun.lock"))) return "bun";
|
|
10382
|
+
if (await fileExists(path26.join(projectPath, "package-lock.json"))) return "npm";
|
|
10174
10383
|
return "npm";
|
|
10175
10384
|
}
|
|
10176
10385
|
function pmRun(pm, scriptName) {
|
|
@@ -10186,7 +10395,7 @@ function pmTest(pm) {
|
|
|
10186
10395
|
return "npm test";
|
|
10187
10396
|
}
|
|
10188
10397
|
async function detectProjectCommands(projectPath) {
|
|
10189
|
-
const pkgPath =
|
|
10398
|
+
const pkgPath = path26.join(projectPath, "package.json");
|
|
10190
10399
|
const pkg = await readJson(pkgPath, null);
|
|
10191
10400
|
if (pkg) {
|
|
10192
10401
|
const pm = await detectPackageManager(projectPath, pkg);
|
|
@@ -10203,27 +10412,27 @@ async function detectProjectCommands(projectPath) {
|
|
|
10203
10412
|
}
|
|
10204
10413
|
return result;
|
|
10205
10414
|
}
|
|
10206
|
-
if (await fileExists(
|
|
10415
|
+
if (await fileExists(path26.join(projectPath, "pytest.ini"))) {
|
|
10207
10416
|
return { stack: "python", test: { tool: "pytest", command: "pytest" } };
|
|
10208
10417
|
}
|
|
10209
|
-
const pyproject = await readFile(
|
|
10418
|
+
const pyproject = await readFile(path26.join(projectPath, "pyproject.toml"), "");
|
|
10210
10419
|
if (pyproject.includes("[tool.pytest") || pyproject.includes("pytest")) {
|
|
10211
10420
|
return { stack: "python", test: { tool: "pytest", command: "pytest" } };
|
|
10212
10421
|
}
|
|
10213
|
-
if (await fileExists(
|
|
10422
|
+
if (await fileExists(path26.join(projectPath, "Cargo.toml"))) {
|
|
10214
10423
|
return { stack: "rust", test: { tool: "cargo", command: "cargo test" } };
|
|
10215
10424
|
}
|
|
10216
|
-
if (await fileExists(
|
|
10425
|
+
if (await fileExists(path26.join(projectPath, "go.mod"))) {
|
|
10217
10426
|
return { stack: "go", test: { tool: "go", command: "go test ./..." } };
|
|
10218
10427
|
}
|
|
10219
10428
|
const files = await listFiles(projectPath);
|
|
10220
10429
|
if (files.some((f) => f.endsWith(".sln") || f.endsWith(".csproj") || f.endsWith(".fsproj"))) {
|
|
10221
10430
|
return { stack: "dotnet", test: { tool: "dotnet", command: "dotnet test" } };
|
|
10222
10431
|
}
|
|
10223
|
-
if (await fileExists(
|
|
10432
|
+
if (await fileExists(path26.join(projectPath, "pom.xml"))) {
|
|
10224
10433
|
return { stack: "java", test: { tool: "maven", command: "mvn test" } };
|
|
10225
10434
|
}
|
|
10226
|
-
if (await fileExists(
|
|
10435
|
+
if (await fileExists(path26.join(projectPath, "gradlew")) && (await fileExists(path26.join(projectPath, "build.gradle")) || await fileExists(path26.join(projectPath, "build.gradle.kts")))) {
|
|
10227
10436
|
return { stack: "java", test: { tool: "gradle", command: "./gradlew test" } };
|
|
10228
10437
|
}
|
|
10229
10438
|
return { stack: "unknown" };
|
|
@@ -10240,7 +10449,7 @@ var init_project_commands = __esm({
|
|
|
10240
10449
|
});
|
|
10241
10450
|
|
|
10242
10451
|
// core/commands/shipping.ts
|
|
10243
|
-
import
|
|
10452
|
+
import path27 from "path";
|
|
10244
10453
|
var ShippingCommands;
|
|
10245
10454
|
var init_shipping = __esm({
|
|
10246
10455
|
"core/commands/shipping.ts"() {
|
|
@@ -10362,7 +10571,7 @@ ${result.stderr}`.trim();
|
|
|
10362
10571
|
*/
|
|
10363
10572
|
async _bumpVersion(projectPath) {
|
|
10364
10573
|
try {
|
|
10365
|
-
const pkgPath =
|
|
10574
|
+
const pkgPath = path27.join(projectPath, "package.json");
|
|
10366
10575
|
const pkg = await file_helper_exports.readJson(pkgPath, { version: "0.0.0" });
|
|
10367
10576
|
const oldVersion = pkg?.version || "0.0.0";
|
|
10368
10577
|
const [major, minor, patch] = oldVersion.split(".").map(Number);
|
|
@@ -10381,7 +10590,7 @@ ${result.stderr}`.trim();
|
|
|
10381
10590
|
*/
|
|
10382
10591
|
async _updateChangelog(feature, version, projectPath) {
|
|
10383
10592
|
try {
|
|
10384
|
-
const changelogPath =
|
|
10593
|
+
const changelogPath = path27.join(projectPath, "CHANGELOG.md");
|
|
10385
10594
|
const changelog = await file_helper_exports.readFile(changelogPath, "# Changelog\n\n");
|
|
10386
10595
|
const entry = `## [${version}] - ${date_helper_default.formatDate(/* @__PURE__ */ new Date())}
|
|
10387
10596
|
|
|
@@ -10722,6 +10931,36 @@ var init_registry = __esm({
|
|
|
10722
10931
|
error: `Command not found: ${name}`
|
|
10723
10932
|
};
|
|
10724
10933
|
}
|
|
10934
|
+
/**
|
|
10935
|
+
* Execute without requiring project (for init, setup commands)
|
|
10936
|
+
* @deprecated Use execute() - it auto-detects based on command metadata
|
|
10937
|
+
*/
|
|
10938
|
+
async executeWithoutProject(name, params, projectPath = process.cwd()) {
|
|
10939
|
+
const handler = this.handlers.get(name);
|
|
10940
|
+
if (handler) {
|
|
10941
|
+
const context = {
|
|
10942
|
+
projectId: "",
|
|
10943
|
+
projectPath,
|
|
10944
|
+
globalPath: "",
|
|
10945
|
+
timestamp: getTimestamp()
|
|
10946
|
+
};
|
|
10947
|
+
return handler.execute(params, context);
|
|
10948
|
+
}
|
|
10949
|
+
const handlerFn = this.handlerFns.get(name);
|
|
10950
|
+
if (handlerFn) {
|
|
10951
|
+
const context = {
|
|
10952
|
+
projectId: "",
|
|
10953
|
+
projectPath,
|
|
10954
|
+
globalPath: "",
|
|
10955
|
+
timestamp: getTimestamp()
|
|
10956
|
+
};
|
|
10957
|
+
return handlerFn(params, context);
|
|
10958
|
+
}
|
|
10959
|
+
return {
|
|
10960
|
+
success: false,
|
|
10961
|
+
error: `Command not found: ${name}`
|
|
10962
|
+
};
|
|
10963
|
+
}
|
|
10725
10964
|
/**
|
|
10726
10965
|
* Clear all registrations (useful for testing)
|
|
10727
10966
|
*/
|
|
@@ -10737,7 +10976,7 @@ var init_registry = __esm({
|
|
|
10737
10976
|
});
|
|
10738
10977
|
|
|
10739
10978
|
// core/commands/analytics.ts
|
|
10740
|
-
import
|
|
10979
|
+
import path28 from "path";
|
|
10741
10980
|
var AnalyticsCommands;
|
|
10742
10981
|
var init_analytics = __esm({
|
|
10743
10982
|
"core/commands/analytics.ts"() {
|
|
@@ -10762,7 +11001,7 @@ var init_analytics = __esm({
|
|
|
10762
11001
|
output_default.fail("no project ID");
|
|
10763
11002
|
return { success: false, error: "No project ID found" };
|
|
10764
11003
|
}
|
|
10765
|
-
const projectName =
|
|
11004
|
+
const projectName = path28.basename(projectPath);
|
|
10766
11005
|
const currentTask = await stateStorage.getCurrentTask(projectId);
|
|
10767
11006
|
const queueTasks = await queueStorage.getActiveTasks(projectId);
|
|
10768
11007
|
const shipped = await shippedStorage.getRecent(projectId, 5);
|
|
@@ -11000,7 +11239,7 @@ ${catInfo?.title || cat}:`);
|
|
|
11000
11239
|
});
|
|
11001
11240
|
|
|
11002
11241
|
// core/commands/cleanup.ts
|
|
11003
|
-
import
|
|
11242
|
+
import path29 from "path";
|
|
11004
11243
|
async function cleanupMemory(projectPath) {
|
|
11005
11244
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
11006
11245
|
const results = { rotated: [], totalSize: 0, freedSpace: 0 };
|
|
@@ -11016,7 +11255,7 @@ async function cleanupMemory(projectPath) {
|
|
|
11016
11255
|
results.totalSize += sizeMB;
|
|
11017
11256
|
const rotated = await jsonl_helper_default.rotateJsonLinesIfNeeded(filePath, 10);
|
|
11018
11257
|
if (rotated) {
|
|
11019
|
-
results.rotated.push(
|
|
11258
|
+
results.rotated.push(path29.basename(filePath));
|
|
11020
11259
|
results.freedSpace += sizeMB;
|
|
11021
11260
|
}
|
|
11022
11261
|
}
|
|
@@ -11107,7 +11346,7 @@ var init_cleanup = __esm({
|
|
|
11107
11346
|
});
|
|
11108
11347
|
|
|
11109
11348
|
// core/commands/design.ts
|
|
11110
|
-
import
|
|
11349
|
+
import path30 from "path";
|
|
11111
11350
|
async function design(target = null, options = {}, projectPath = process.cwd()) {
|
|
11112
11351
|
try {
|
|
11113
11352
|
const designType = options.type || "architecture";
|
|
@@ -11119,7 +11358,7 @@ async function design(target = null, options = {}, projectPath = process.cwd())
|
|
|
11119
11358
|
const designTarget = target || "system";
|
|
11120
11359
|
output_default.spin(`designing ${designType}...`);
|
|
11121
11360
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
11122
|
-
const designsPath =
|
|
11361
|
+
const designsPath = path30.join(
|
|
11123
11362
|
path_manager_default.getGlobalProjectPath(projectId),
|
|
11124
11363
|
"planning",
|
|
11125
11364
|
"designs"
|
|
@@ -11159,7 +11398,7 @@ async function design(target = null, options = {}, projectPath = process.cwd())
|
|
|
11159
11398
|
break;
|
|
11160
11399
|
}
|
|
11161
11400
|
const designFileName = `${designType}-${designTarget.toLowerCase().replace(/\s+/g, "-")}.md`;
|
|
11162
|
-
const designFilePath =
|
|
11401
|
+
const designFilePath = path30.join(designsPath, designFileName);
|
|
11163
11402
|
await file_helper_exports.writeFile(designFilePath, designContent);
|
|
11164
11403
|
await memoryService.log(projectPath, "design_created", {
|
|
11165
11404
|
type: designType,
|
|
@@ -11183,7 +11422,7 @@ var init_design = __esm({
|
|
|
11183
11422
|
});
|
|
11184
11423
|
|
|
11185
11424
|
// core/commands/snapshots.ts
|
|
11186
|
-
import
|
|
11425
|
+
import path31 from "path";
|
|
11187
11426
|
async function recover(projectPath = process.cwd()) {
|
|
11188
11427
|
try {
|
|
11189
11428
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
@@ -11231,7 +11470,7 @@ async function undo(projectPath = process.cwd()) {
|
|
|
11231
11470
|
output_default.fail("no project ID");
|
|
11232
11471
|
return { success: false, error: "No project ID found" };
|
|
11233
11472
|
}
|
|
11234
|
-
const snapshotsPath =
|
|
11473
|
+
const snapshotsPath = path31.join(
|
|
11235
11474
|
path_manager_default.getGlobalProjectPath(projectId),
|
|
11236
11475
|
"snapshots"
|
|
11237
11476
|
);
|
|
@@ -11252,7 +11491,7 @@ async function undo(projectPath = process.cwd()) {
|
|
|
11252
11491
|
cwd: projectPath,
|
|
11253
11492
|
encoding: "utf-8"
|
|
11254
11493
|
});
|
|
11255
|
-
const snapshotFile =
|
|
11494
|
+
const snapshotFile = path31.join(snapshotsPath, "history.json");
|
|
11256
11495
|
let history2 = { snapshots: [], current: -1 };
|
|
11257
11496
|
try {
|
|
11258
11497
|
const content = await file_helper_exports.readFile(snapshotFile);
|
|
@@ -11289,11 +11528,11 @@ async function redo(projectPath = process.cwd()) {
|
|
|
11289
11528
|
output_default.fail("no project ID");
|
|
11290
11529
|
return { success: false, error: "No project ID found" };
|
|
11291
11530
|
}
|
|
11292
|
-
const snapshotsPath =
|
|
11531
|
+
const snapshotsPath = path31.join(
|
|
11293
11532
|
path_manager_default.getGlobalProjectPath(projectId),
|
|
11294
11533
|
"snapshots"
|
|
11295
11534
|
);
|
|
11296
|
-
const snapshotFile =
|
|
11535
|
+
const snapshotFile = path31.join(snapshotsPath, "history.json");
|
|
11297
11536
|
let history2;
|
|
11298
11537
|
try {
|
|
11299
11538
|
const content = await file_helper_exports.readFile(snapshotFile);
|
|
@@ -11349,11 +11588,11 @@ async function history(projectPath = process.cwd()) {
|
|
|
11349
11588
|
output_default.fail("no project ID");
|
|
11350
11589
|
return { success: false, error: "No project ID found" };
|
|
11351
11590
|
}
|
|
11352
|
-
const snapshotsPath =
|
|
11591
|
+
const snapshotsPath = path31.join(
|
|
11353
11592
|
path_manager_default.getGlobalProjectPath(projectId),
|
|
11354
11593
|
"snapshots"
|
|
11355
11594
|
);
|
|
11356
|
-
const snapshotFile =
|
|
11595
|
+
const snapshotFile = path31.join(snapshotsPath, "history.json");
|
|
11357
11596
|
let snapshotHistory;
|
|
11358
11597
|
try {
|
|
11359
11598
|
const content = await file_helper_exports.readFile(snapshotFile);
|
|
@@ -11455,9 +11694,9 @@ var init_maintenance = __esm({
|
|
|
11455
11694
|
});
|
|
11456
11695
|
|
|
11457
11696
|
// core/commands/setup.ts
|
|
11458
|
-
import
|
|
11459
|
-
import
|
|
11460
|
-
import
|
|
11697
|
+
import path32 from "path";
|
|
11698
|
+
import fs25 from "fs";
|
|
11699
|
+
import os11 from "os";
|
|
11461
11700
|
import chalk4 from "chalk";
|
|
11462
11701
|
var SetupCommands;
|
|
11463
11702
|
var init_setup2 = __esm({
|
|
@@ -11564,9 +11803,9 @@ var init_setup2 = __esm({
|
|
|
11564
11803
|
*/
|
|
11565
11804
|
async installStatusLine() {
|
|
11566
11805
|
try {
|
|
11567
|
-
const claudeDir =
|
|
11568
|
-
const settingsPath =
|
|
11569
|
-
const statusLinePath =
|
|
11806
|
+
const claudeDir = path32.join(os11.homedir(), ".claude");
|
|
11807
|
+
const settingsPath = path32.join(claudeDir, "settings.json");
|
|
11808
|
+
const statusLinePath = path32.join(claudeDir, "prjct-statusline.sh");
|
|
11570
11809
|
const scriptContent = `#!/bin/bash
|
|
11571
11810
|
# prjct Status Line for Claude Code
|
|
11572
11811
|
# Shows version update notifications and current task
|
|
@@ -11624,11 +11863,11 @@ fi
|
|
|
11624
11863
|
# Default: show prjct branding
|
|
11625
11864
|
echo "\u26A1 prjct"
|
|
11626
11865
|
`;
|
|
11627
|
-
|
|
11866
|
+
fs25.writeFileSync(statusLinePath, scriptContent, { mode: 493 });
|
|
11628
11867
|
let settings = {};
|
|
11629
|
-
if (
|
|
11868
|
+
if (fs25.existsSync(settingsPath)) {
|
|
11630
11869
|
try {
|
|
11631
|
-
settings = JSON.parse(
|
|
11870
|
+
settings = JSON.parse(fs25.readFileSync(settingsPath, "utf8"));
|
|
11632
11871
|
} catch {
|
|
11633
11872
|
}
|
|
11634
11873
|
}
|
|
@@ -11636,7 +11875,7 @@ echo "\u26A1 prjct"
|
|
|
11636
11875
|
type: "command",
|
|
11637
11876
|
command: statusLinePath
|
|
11638
11877
|
};
|
|
11639
|
-
|
|
11878
|
+
fs25.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
11640
11879
|
return { success: true };
|
|
11641
11880
|
} catch (error) {
|
|
11642
11881
|
return { success: false, error: error.message };
|
|
@@ -11741,6 +11980,9 @@ var init_commands = __esm({
|
|
|
11741
11980
|
this.prjctDir = ".prjct";
|
|
11742
11981
|
}
|
|
11743
11982
|
// ========== Workflow Commands ==========
|
|
11983
|
+
async work(task = null, projectPath = process.cwd()) {
|
|
11984
|
+
return this.workflow.now(task, projectPath);
|
|
11985
|
+
}
|
|
11744
11986
|
async done(projectPath = process.cwd()) {
|
|
11745
11987
|
return this.workflow.done(projectPath);
|
|
11746
11988
|
}
|
|
@@ -11757,6 +11999,9 @@ var init_commands = __esm({
|
|
|
11757
11999
|
async init(idea = null, projectPath = process.cwd()) {
|
|
11758
12000
|
return this.planning.init(idea, projectPath);
|
|
11759
12001
|
}
|
|
12002
|
+
async feature(description, projectPath = process.cwd()) {
|
|
12003
|
+
return this.planning.feature(description, projectPath);
|
|
12004
|
+
}
|
|
11760
12005
|
async bug(description, projectPath = process.cwd()) {
|
|
11761
12006
|
return this.planning.bug(description, projectPath);
|
|
11762
12007
|
}
|
|
@@ -11897,6 +12142,17 @@ var init_command_data = __esm({
|
|
|
11897
12142
|
requiresProject: true,
|
|
11898
12143
|
features: ["Agentic type classification", "7-phase workflow", "Git branch management", "Task breakdown"]
|
|
11899
12144
|
},
|
|
12145
|
+
{
|
|
12146
|
+
name: "feature",
|
|
12147
|
+
group: "core",
|
|
12148
|
+
description: "DEPRECATED - Use /p:task instead",
|
|
12149
|
+
usage: { claude: '/p:task "<description>"', terminal: 'prjct task "<description>"' },
|
|
12150
|
+
params: "<description>",
|
|
12151
|
+
implemented: true,
|
|
12152
|
+
hasTemplate: true,
|
|
12153
|
+
requiresProject: true,
|
|
12154
|
+
deprecated: true
|
|
12155
|
+
},
|
|
11900
12156
|
{
|
|
11901
12157
|
name: "spec",
|
|
11902
12158
|
group: "core",
|
|
@@ -11907,6 +12163,28 @@ var init_command_data = __esm({
|
|
|
11907
12163
|
hasTemplate: true,
|
|
11908
12164
|
requiresProject: true
|
|
11909
12165
|
},
|
|
12166
|
+
{
|
|
12167
|
+
name: "now",
|
|
12168
|
+
group: "core",
|
|
12169
|
+
description: "DEPRECATED - Use /p:task instead",
|
|
12170
|
+
usage: { claude: '/p:task "<description>"', terminal: 'prjct task "<description>"' },
|
|
12171
|
+
params: "[task]",
|
|
12172
|
+
implemented: true,
|
|
12173
|
+
hasTemplate: true,
|
|
12174
|
+
requiresProject: true,
|
|
12175
|
+
deprecated: true
|
|
12176
|
+
},
|
|
12177
|
+
{
|
|
12178
|
+
name: "work",
|
|
12179
|
+
group: "core",
|
|
12180
|
+
description: "DEPRECATED - Use /p:task instead",
|
|
12181
|
+
usage: { claude: '/p:task "<description>"', terminal: 'prjct task "<description>"' },
|
|
12182
|
+
params: "[task]",
|
|
12183
|
+
implemented: true,
|
|
12184
|
+
hasTemplate: true,
|
|
12185
|
+
requiresProject: true,
|
|
12186
|
+
deprecated: true
|
|
12187
|
+
},
|
|
11910
12188
|
{
|
|
11911
12189
|
name: "pause",
|
|
11912
12190
|
group: "core",
|
|
@@ -12221,7 +12499,7 @@ var init_commands2 = __esm({
|
|
|
12221
12499
|
init_commands();
|
|
12222
12500
|
init_registry();
|
|
12223
12501
|
init_register();
|
|
12224
|
-
|
|
12502
|
+
init_types2();
|
|
12225
12503
|
}
|
|
12226
12504
|
});
|
|
12227
12505
|
|
|
@@ -12230,7 +12508,7 @@ var require_package = __commonJS({
|
|
|
12230
12508
|
"package.json"(exports, module) {
|
|
12231
12509
|
module.exports = {
|
|
12232
12510
|
name: "prjct-cli",
|
|
12233
|
-
version: "0.28.
|
|
12511
|
+
version: "0.28.0",
|
|
12234
12512
|
description: "Built for Claude - Ship fast, track progress, stay focused. Developer momentum tool for indie hackers.",
|
|
12235
12513
|
main: "core/index.ts",
|
|
12236
12514
|
bin: {
|
|
@@ -12278,6 +12556,7 @@ var require_package = __commonJS({
|
|
|
12278
12556
|
license: "MIT",
|
|
12279
12557
|
dependencies: {
|
|
12280
12558
|
"@hono/node-server": "^1.13.7",
|
|
12559
|
+
"@linear/sdk": "^29.0.0",
|
|
12281
12560
|
chalk: "^4.1.2",
|
|
12282
12561
|
esbuild: "^0.25.0",
|
|
12283
12562
|
glob: "^10.3.10",
|
|
@@ -12390,12 +12669,14 @@ Use 'prjct --help' to see available commands.`);
|
|
|
12390
12669
|
const param = parsedArgs.join(" ") || null;
|
|
12391
12670
|
const standardCommands = {
|
|
12392
12671
|
// Core workflow
|
|
12672
|
+
work: /* @__PURE__ */ __name((p) => commands.work(p), "work"),
|
|
12393
12673
|
done: /* @__PURE__ */ __name(() => commands.done(), "done"),
|
|
12394
12674
|
next: /* @__PURE__ */ __name(() => commands.next(), "next"),
|
|
12395
12675
|
pause: /* @__PURE__ */ __name((p) => commands.pause(p || ""), "pause"),
|
|
12396
12676
|
resume: /* @__PURE__ */ __name((p) => commands.resume(p), "resume"),
|
|
12397
12677
|
// Planning
|
|
12398
12678
|
init: /* @__PURE__ */ __name((p) => commands.init(p), "init"),
|
|
12679
|
+
feature: /* @__PURE__ */ __name((p) => commands.feature(p || ""), "feature"),
|
|
12399
12680
|
bug: /* @__PURE__ */ __name((p) => commands.bug(p || ""), "bug"),
|
|
12400
12681
|
idea: /* @__PURE__ */ __name((p) => commands.idea(p || ""), "idea"),
|
|
12401
12682
|
spec: /* @__PURE__ */ __name((p) => commands.spec(p), "spec"),
|
|
@@ -12503,7 +12784,7 @@ init_version();
|
|
|
12503
12784
|
init_editors_config();
|
|
12504
12785
|
|
|
12505
12786
|
// core/server/server.ts
|
|
12506
|
-
import { Hono as
|
|
12787
|
+
import { Hono as Hono3 } from "hono";
|
|
12507
12788
|
import { cors } from "hono/cors";
|
|
12508
12789
|
import { logger } from "hono/logger";
|
|
12509
12790
|
|
|
@@ -12632,6 +12913,410 @@ function createRoutes(projectId, _projectPath) {
|
|
|
12632
12913
|
}
|
|
12633
12914
|
__name(createRoutes, "createRoutes");
|
|
12634
12915
|
|
|
12916
|
+
// core/server/routes-extended.ts
|
|
12917
|
+
import { Hono as Hono2 } from "hono";
|
|
12918
|
+
import fs4 from "fs/promises";
|
|
12919
|
+
import path4 from "path";
|
|
12920
|
+
import os2 from "os";
|
|
12921
|
+
import * as jsonc2 from "jsonc-parser";
|
|
12922
|
+
var GLOBAL_BASE = path4.join(os2.homedir(), ".prjct-cli");
|
|
12923
|
+
var PROJECTS_DIR = path4.join(GLOBAL_BASE, "projects");
|
|
12924
|
+
async function readJsonFile2(filePath) {
|
|
12925
|
+
try {
|
|
12926
|
+
const content = await fs4.readFile(filePath, "utf-8");
|
|
12927
|
+
const errors = [];
|
|
12928
|
+
const result = jsonc2.parse(content, errors);
|
|
12929
|
+
return errors.length > 0 ? null : result;
|
|
12930
|
+
} catch {
|
|
12931
|
+
return null;
|
|
12932
|
+
}
|
|
12933
|
+
}
|
|
12934
|
+
__name(readJsonFile2, "readJsonFile");
|
|
12935
|
+
async function writeJsonFile2(filePath, data) {
|
|
12936
|
+
try {
|
|
12937
|
+
await fs4.mkdir(path4.dirname(filePath), { recursive: true });
|
|
12938
|
+
await fs4.writeFile(filePath, JSON.stringify(data, null, 2) + "\n", "utf-8");
|
|
12939
|
+
return true;
|
|
12940
|
+
} catch {
|
|
12941
|
+
return false;
|
|
12942
|
+
}
|
|
12943
|
+
}
|
|
12944
|
+
__name(writeJsonFile2, "writeJsonFile");
|
|
12945
|
+
function getProjectPath(projectId) {
|
|
12946
|
+
return path4.join(PROJECTS_DIR, projectId);
|
|
12947
|
+
}
|
|
12948
|
+
__name(getProjectPath, "getProjectPath");
|
|
12949
|
+
async function getProjectConfig(projectId) {
|
|
12950
|
+
const configPath = path4.join(getProjectPath(projectId), "project.json");
|
|
12951
|
+
return await readJsonFile2(configPath);
|
|
12952
|
+
}
|
|
12953
|
+
__name(getProjectConfig, "getProjectConfig");
|
|
12954
|
+
async function calculateDuration(startedAt) {
|
|
12955
|
+
if (!startedAt) return "";
|
|
12956
|
+
const start = new Date(startedAt);
|
|
12957
|
+
const now = /* @__PURE__ */ new Date();
|
|
12958
|
+
const elapsed = now.getTime() - start.getTime();
|
|
12959
|
+
const hours = Math.floor(elapsed / (1e3 * 60 * 60));
|
|
12960
|
+
const minutes = Math.floor(elapsed % (1e3 * 60 * 60) / (1e3 * 60));
|
|
12961
|
+
if (hours > 0) {
|
|
12962
|
+
return `${hours}h ${minutes}m`;
|
|
12963
|
+
}
|
|
12964
|
+
return `${minutes}m`;
|
|
12965
|
+
}
|
|
12966
|
+
__name(calculateDuration, "calculateDuration");
|
|
12967
|
+
function createExtendedRoutes() {
|
|
12968
|
+
const api = new Hono2();
|
|
12969
|
+
api.get("/projects", async (c) => {
|
|
12970
|
+
try {
|
|
12971
|
+
await fs4.mkdir(PROJECTS_DIR, { recursive: true });
|
|
12972
|
+
const entries = await fs4.readdir(PROJECTS_DIR, { withFileTypes: true });
|
|
12973
|
+
const projectIds = entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
12974
|
+
const projects = await Promise.all(
|
|
12975
|
+
projectIds.map(async (id) => {
|
|
12976
|
+
const projectPath = getProjectPath(id);
|
|
12977
|
+
const config = await getProjectConfig(id);
|
|
12978
|
+
const state = await readJsonFile2(
|
|
12979
|
+
path4.join(projectPath, "storage/state.json")
|
|
12980
|
+
);
|
|
12981
|
+
const queue = await readJsonFile2(
|
|
12982
|
+
path4.join(projectPath, "storage/queue.json")
|
|
12983
|
+
);
|
|
12984
|
+
const ideas = await readJsonFile2(
|
|
12985
|
+
path4.join(projectPath, "storage/ideas.json")
|
|
12986
|
+
);
|
|
12987
|
+
const shipped = await readJsonFile2(
|
|
12988
|
+
path4.join(projectPath, "storage/shipped.json")
|
|
12989
|
+
);
|
|
12990
|
+
const currentTask = state?.currentTask;
|
|
12991
|
+
const duration = await calculateDuration(currentTask?.startedAt);
|
|
12992
|
+
return {
|
|
12993
|
+
id,
|
|
12994
|
+
name: config?.name || id.slice(0, 8),
|
|
12995
|
+
path: config?.path || null,
|
|
12996
|
+
currentTask: currentTask ? {
|
|
12997
|
+
...currentTask,
|
|
12998
|
+
duration
|
|
12999
|
+
} : null,
|
|
13000
|
+
pausedTask: state?.previousTask || null,
|
|
13001
|
+
stats: {
|
|
13002
|
+
queueCount: queue?.tasks?.filter((t) => !t.completed)?.length || 0,
|
|
13003
|
+
ideasCount: ideas?.ideas?.filter((i) => i.status === "pending")?.length || 0,
|
|
13004
|
+
shippedCount: shipped?.shipped?.length || 0
|
|
13005
|
+
}
|
|
13006
|
+
};
|
|
13007
|
+
})
|
|
13008
|
+
);
|
|
13009
|
+
projects.sort((a, b) => {
|
|
13010
|
+
if (a.currentTask && !b.currentTask) return -1;
|
|
13011
|
+
if (!a.currentTask && b.currentTask) return 1;
|
|
13012
|
+
return (a.name || "").localeCompare(b.name || "");
|
|
13013
|
+
});
|
|
13014
|
+
return c.json({ projects });
|
|
13015
|
+
} catch (error) {
|
|
13016
|
+
return c.json({ projects: [], error: String(error) }, 500);
|
|
13017
|
+
}
|
|
13018
|
+
});
|
|
13019
|
+
api.get("/projects/:id/full", async (c) => {
|
|
13020
|
+
const projectId = c.req.param("id");
|
|
13021
|
+
const projectPath = getProjectPath(projectId);
|
|
13022
|
+
try {
|
|
13023
|
+
const [config, state, queue, ideas, shipped, roadmap] = await Promise.all([
|
|
13024
|
+
getProjectConfig(projectId),
|
|
13025
|
+
readJsonFile2(path4.join(projectPath, "storage/state.json")),
|
|
13026
|
+
readJsonFile2(path4.join(projectPath, "storage/queue.json")),
|
|
13027
|
+
readJsonFile2(path4.join(projectPath, "storage/ideas.json")),
|
|
13028
|
+
readJsonFile2(path4.join(projectPath, "storage/shipped.json")),
|
|
13029
|
+
readJsonFile2(path4.join(projectPath, "planning/roadmap.json"))
|
|
13030
|
+
]);
|
|
13031
|
+
if (state?.currentTask?.startedAt) {
|
|
13032
|
+
state.currentTask.duration = await calculateDuration(state.currentTask.startedAt);
|
|
13033
|
+
}
|
|
13034
|
+
const now = /* @__PURE__ */ new Date();
|
|
13035
|
+
const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
13036
|
+
const weekStart = new Date(todayStart);
|
|
13037
|
+
weekStart.setDate(weekStart.getDate() - weekStart.getDay());
|
|
13038
|
+
const completedToday = queue?.tasks?.filter((t) => {
|
|
13039
|
+
if (!t.completed || !t.completedAt) return false;
|
|
13040
|
+
return new Date(t.completedAt) >= todayStart;
|
|
13041
|
+
})?.length || 0;
|
|
13042
|
+
const completedThisWeek = queue?.tasks?.filter((t) => {
|
|
13043
|
+
if (!t.completed || !t.completedAt) return false;
|
|
13044
|
+
return new Date(t.completedAt) >= weekStart;
|
|
13045
|
+
})?.length || 0;
|
|
13046
|
+
return c.json({
|
|
13047
|
+
id: projectId,
|
|
13048
|
+
name: config?.name || projectId,
|
|
13049
|
+
path: config?.path,
|
|
13050
|
+
state: state || { currentTask: null, previousTask: null, lastUpdated: "" },
|
|
13051
|
+
queue: queue || { tasks: [], lastUpdated: "" },
|
|
13052
|
+
ideas: ideas || { ideas: [], lastUpdated: "" },
|
|
13053
|
+
shipped: shipped || { shipped: [], lastUpdated: "" },
|
|
13054
|
+
roadmap: roadmap || { features: [], backlog: [], lastUpdated: "" },
|
|
13055
|
+
stats: {
|
|
13056
|
+
tasksToday: completedToday,
|
|
13057
|
+
tasksThisWeek: completedThisWeek,
|
|
13058
|
+
queueCount: queue?.tasks?.filter((t) => !t.completed)?.length || 0,
|
|
13059
|
+
ideasCount: ideas?.ideas?.filter((i) => i.status === "pending")?.length || 0,
|
|
13060
|
+
shippedCount: shipped?.shipped?.length || 0
|
|
13061
|
+
},
|
|
13062
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
13063
|
+
});
|
|
13064
|
+
} catch (error) {
|
|
13065
|
+
return c.json({ error: String(error) }, 500);
|
|
13066
|
+
}
|
|
13067
|
+
});
|
|
13068
|
+
api.post("/projects/:id/task/complete", async (c) => {
|
|
13069
|
+
const projectId = c.req.param("id");
|
|
13070
|
+
const projectPath = getProjectPath(projectId);
|
|
13071
|
+
const statePath = path4.join(projectPath, "storage/state.json");
|
|
13072
|
+
try {
|
|
13073
|
+
const state = await readJsonFile2(statePath);
|
|
13074
|
+
if (!state?.currentTask) {
|
|
13075
|
+
return c.json({ success: false, error: "No active task" }, 400);
|
|
13076
|
+
}
|
|
13077
|
+
const completedTask = state.currentTask;
|
|
13078
|
+
const newState = {
|
|
13079
|
+
currentTask: null,
|
|
13080
|
+
previousTask: null,
|
|
13081
|
+
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
13082
|
+
};
|
|
13083
|
+
await writeJsonFile2(statePath, newState);
|
|
13084
|
+
return c.json({
|
|
13085
|
+
success: true,
|
|
13086
|
+
completedTask,
|
|
13087
|
+
message: `Completed: ${completedTask.description}`
|
|
13088
|
+
});
|
|
13089
|
+
} catch (error) {
|
|
13090
|
+
return c.json({ success: false, error: String(error) }, 500);
|
|
13091
|
+
}
|
|
13092
|
+
});
|
|
13093
|
+
api.post("/projects/:id/task/pause", async (c) => {
|
|
13094
|
+
const projectId = c.req.param("id");
|
|
13095
|
+
const projectPath = getProjectPath(projectId);
|
|
13096
|
+
const statePath = path4.join(projectPath, "storage/state.json");
|
|
13097
|
+
try {
|
|
13098
|
+
const body = await c.req.json().catch(() => ({}));
|
|
13099
|
+
const reason2 = body.reason;
|
|
13100
|
+
const state = await readJsonFile2(statePath);
|
|
13101
|
+
if (!state?.currentTask) {
|
|
13102
|
+
return c.json({ success: false, error: "No active task" }, 400);
|
|
13103
|
+
}
|
|
13104
|
+
const pausedTask = {
|
|
13105
|
+
id: state.currentTask.id,
|
|
13106
|
+
description: state.currentTask.description,
|
|
13107
|
+
status: "paused",
|
|
13108
|
+
startedAt: state.currentTask.startedAt,
|
|
13109
|
+
pausedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
13110
|
+
pauseReason: reason2
|
|
13111
|
+
};
|
|
13112
|
+
const newState = {
|
|
13113
|
+
currentTask: null,
|
|
13114
|
+
previousTask: pausedTask,
|
|
13115
|
+
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
13116
|
+
};
|
|
13117
|
+
await writeJsonFile2(statePath, newState);
|
|
13118
|
+
return c.json({
|
|
13119
|
+
success: true,
|
|
13120
|
+
pausedTask,
|
|
13121
|
+
message: `Paused: ${pausedTask.description}`
|
|
13122
|
+
});
|
|
13123
|
+
} catch (error) {
|
|
13124
|
+
return c.json({ success: false, error: String(error) }, 500);
|
|
13125
|
+
}
|
|
13126
|
+
});
|
|
13127
|
+
api.post("/projects/:id/task/resume", async (c) => {
|
|
13128
|
+
const projectId = c.req.param("id");
|
|
13129
|
+
const projectPath = getProjectPath(projectId);
|
|
13130
|
+
const statePath = path4.join(projectPath, "storage/state.json");
|
|
13131
|
+
try {
|
|
13132
|
+
const state = await readJsonFile2(statePath);
|
|
13133
|
+
if (!state?.previousTask) {
|
|
13134
|
+
return c.json({ success: false, error: "No paused task" }, 400);
|
|
13135
|
+
}
|
|
13136
|
+
const resumedTask = {
|
|
13137
|
+
id: state.previousTask.id,
|
|
13138
|
+
description: state.previousTask.description,
|
|
13139
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
13140
|
+
sessionId: `sess_${Date.now().toString(36)}`
|
|
13141
|
+
};
|
|
13142
|
+
const newState = {
|
|
13143
|
+
currentTask: resumedTask,
|
|
13144
|
+
previousTask: null,
|
|
13145
|
+
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
13146
|
+
};
|
|
13147
|
+
await writeJsonFile2(statePath, newState);
|
|
13148
|
+
return c.json({
|
|
13149
|
+
success: true,
|
|
13150
|
+
resumedTask,
|
|
13151
|
+
message: `Resumed: ${resumedTask.description}`
|
|
13152
|
+
});
|
|
13153
|
+
} catch (error) {
|
|
13154
|
+
return c.json({ success: false, error: String(error) }, 500);
|
|
13155
|
+
}
|
|
13156
|
+
});
|
|
13157
|
+
api.post("/projects/:id/queue/start", async (c) => {
|
|
13158
|
+
const projectId = c.req.param("id");
|
|
13159
|
+
const projectPath = getProjectPath(projectId);
|
|
13160
|
+
const statePath = path4.join(projectPath, "storage/state.json");
|
|
13161
|
+
const queuePath = path4.join(projectPath, "storage/queue.json");
|
|
13162
|
+
try {
|
|
13163
|
+
const body = await c.req.json();
|
|
13164
|
+
const { taskId } = body;
|
|
13165
|
+
if (!taskId) {
|
|
13166
|
+
return c.json({ success: false, error: "taskId required" }, 400);
|
|
13167
|
+
}
|
|
13168
|
+
const state = await readJsonFile2(statePath);
|
|
13169
|
+
const queue = await readJsonFile2(queuePath);
|
|
13170
|
+
if (state?.currentTask) {
|
|
13171
|
+
return c.json({ success: false, error: "Complete or pause current task first" }, 400);
|
|
13172
|
+
}
|
|
13173
|
+
const task = queue?.tasks?.find((t) => t.id === taskId);
|
|
13174
|
+
if (!task) {
|
|
13175
|
+
return c.json({ success: false, error: "Task not found in queue" }, 404);
|
|
13176
|
+
}
|
|
13177
|
+
const newTask = {
|
|
13178
|
+
id: task.id,
|
|
13179
|
+
description: task.description,
|
|
13180
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
13181
|
+
sessionId: `sess_${Date.now().toString(36)}`,
|
|
13182
|
+
featureId: task.featureId
|
|
13183
|
+
};
|
|
13184
|
+
const newState = {
|
|
13185
|
+
currentTask: newTask,
|
|
13186
|
+
previousTask: null,
|
|
13187
|
+
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
13188
|
+
};
|
|
13189
|
+
await writeJsonFile2(statePath, newState);
|
|
13190
|
+
return c.json({
|
|
13191
|
+
success: true,
|
|
13192
|
+
task: newTask,
|
|
13193
|
+
message: `Started: ${newTask.description}`
|
|
13194
|
+
});
|
|
13195
|
+
} catch (error) {
|
|
13196
|
+
return c.json({ success: false, error: String(error) }, 500);
|
|
13197
|
+
}
|
|
13198
|
+
});
|
|
13199
|
+
api.post("/projects/:id/ideas", async (c) => {
|
|
13200
|
+
const projectId = c.req.param("id");
|
|
13201
|
+
const projectPath = getProjectPath(projectId);
|
|
13202
|
+
const ideasPath = path4.join(projectPath, "storage/ideas.json");
|
|
13203
|
+
try {
|
|
13204
|
+
const body = await c.req.json();
|
|
13205
|
+
const { text, priority = "medium", tags = [] } = body;
|
|
13206
|
+
if (!text) {
|
|
13207
|
+
return c.json({ success: false, error: "text required" }, 400);
|
|
13208
|
+
}
|
|
13209
|
+
const ideas = await readJsonFile2(ideasPath) || { ideas: [], lastUpdated: "" };
|
|
13210
|
+
const newIdea = {
|
|
13211
|
+
id: `idea_${Date.now().toString(36)}`,
|
|
13212
|
+
text,
|
|
13213
|
+
status: "pending",
|
|
13214
|
+
priority,
|
|
13215
|
+
tags,
|
|
13216
|
+
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
13217
|
+
};
|
|
13218
|
+
ideas.ideas.unshift(newIdea);
|
|
13219
|
+
ideas.lastUpdated = (/* @__PURE__ */ new Date()).toISOString();
|
|
13220
|
+
await writeJsonFile2(ideasPath, ideas);
|
|
13221
|
+
return c.json({
|
|
13222
|
+
success: true,
|
|
13223
|
+
idea: newIdea,
|
|
13224
|
+
message: `Captured: ${text.slice(0, 50)}...`
|
|
13225
|
+
});
|
|
13226
|
+
} catch (error) {
|
|
13227
|
+
return c.json({ success: false, error: String(error) }, 500);
|
|
13228
|
+
}
|
|
13229
|
+
});
|
|
13230
|
+
api.get("/stats/global", async (c) => {
|
|
13231
|
+
try {
|
|
13232
|
+
await fs4.mkdir(PROJECTS_DIR, { recursive: true });
|
|
13233
|
+
const entries = await fs4.readdir(PROJECTS_DIR, { withFileTypes: true });
|
|
13234
|
+
const projectIds = entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
13235
|
+
let totalTasks = 0;
|
|
13236
|
+
let totalIdeas = 0;
|
|
13237
|
+
let totalShipped = 0;
|
|
13238
|
+
let activeProjects = 0;
|
|
13239
|
+
for (const id of projectIds) {
|
|
13240
|
+
const projectPath = getProjectPath(id);
|
|
13241
|
+
const state = await readJsonFile2(path4.join(projectPath, "storage/state.json"));
|
|
13242
|
+
const queue = await readJsonFile2(path4.join(projectPath, "storage/queue.json"));
|
|
13243
|
+
const ideas = await readJsonFile2(path4.join(projectPath, "storage/ideas.json"));
|
|
13244
|
+
const shipped = await readJsonFile2(path4.join(projectPath, "storage/shipped.json"));
|
|
13245
|
+
if (state?.currentTask) activeProjects++;
|
|
13246
|
+
totalTasks += queue?.tasks?.filter((t) => !t.completed)?.length || 0;
|
|
13247
|
+
totalIdeas += ideas?.ideas?.filter((i) => i.status === "pending")?.length || 0;
|
|
13248
|
+
totalShipped += shipped?.shipped?.length || 0;
|
|
13249
|
+
}
|
|
13250
|
+
return c.json({
|
|
13251
|
+
totalProjects: projectIds.length,
|
|
13252
|
+
activeProjects,
|
|
13253
|
+
totalTasks,
|
|
13254
|
+
totalIdeas,
|
|
13255
|
+
totalShipped,
|
|
13256
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
13257
|
+
});
|
|
13258
|
+
} catch (error) {
|
|
13259
|
+
return c.json({ error: String(error) }, 500);
|
|
13260
|
+
}
|
|
13261
|
+
});
|
|
13262
|
+
api.get("/status-bar/compact", async (c) => {
|
|
13263
|
+
try {
|
|
13264
|
+
const cwd = c.req.query("cwd");
|
|
13265
|
+
await fs4.mkdir(PROJECTS_DIR, { recursive: true });
|
|
13266
|
+
const entries = await fs4.readdir(PROJECTS_DIR, { withFileTypes: true });
|
|
13267
|
+
const projectIds = entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
13268
|
+
let targetProjectId = null;
|
|
13269
|
+
if (cwd) {
|
|
13270
|
+
for (const id of projectIds) {
|
|
13271
|
+
const config = await getProjectConfig(id);
|
|
13272
|
+
const projectPath = config?.repoPath || config?.path;
|
|
13273
|
+
if (projectPath && cwd.startsWith(projectPath)) {
|
|
13274
|
+
targetProjectId = id;
|
|
13275
|
+
break;
|
|
13276
|
+
}
|
|
13277
|
+
}
|
|
13278
|
+
}
|
|
13279
|
+
let activeProject = null;
|
|
13280
|
+
let activeTask = null;
|
|
13281
|
+
let pausedTask = null;
|
|
13282
|
+
const idsToCheck = targetProjectId ? [targetProjectId] : projectIds;
|
|
13283
|
+
for (const id of idsToCheck) {
|
|
13284
|
+
const projectPath = getProjectPath(id);
|
|
13285
|
+
const state = await readJsonFile2(path4.join(projectPath, "storage/state.json"));
|
|
13286
|
+
const config = await getProjectConfig(id);
|
|
13287
|
+
if (state?.currentTask) {
|
|
13288
|
+
activeProject = { id, name: config?.name || id, path: config?.repoPath || config?.path };
|
|
13289
|
+
activeTask = {
|
|
13290
|
+
...state.currentTask,
|
|
13291
|
+
duration: await calculateDuration(state.currentTask.startedAt)
|
|
13292
|
+
};
|
|
13293
|
+
break;
|
|
13294
|
+
}
|
|
13295
|
+
if (state?.previousTask && !pausedTask) {
|
|
13296
|
+
activeProject = { id, name: config?.name || id, path: config?.repoPath || config?.path };
|
|
13297
|
+
pausedTask = state.previousTask;
|
|
13298
|
+
}
|
|
13299
|
+
}
|
|
13300
|
+
return c.json({
|
|
13301
|
+
hasActiveTask: !!activeTask,
|
|
13302
|
+
hasPausedTask: !!pausedTask,
|
|
13303
|
+
activeProject,
|
|
13304
|
+
activeTask,
|
|
13305
|
+
pausedTask,
|
|
13306
|
+
totalProjects: projectIds.length,
|
|
13307
|
+
// Include whether we filtered by cwd
|
|
13308
|
+
filtered: !!targetProjectId,
|
|
13309
|
+
cwd: cwd || null,
|
|
13310
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
13311
|
+
});
|
|
13312
|
+
} catch (error) {
|
|
13313
|
+
return c.json({ error: String(error) }, 500);
|
|
13314
|
+
}
|
|
13315
|
+
});
|
|
13316
|
+
return api;
|
|
13317
|
+
}
|
|
13318
|
+
__name(createExtendedRoutes, "createExtendedRoutes");
|
|
13319
|
+
|
|
12635
13320
|
// core/server/sse.ts
|
|
12636
13321
|
import { streamSSE } from "hono/streaming";
|
|
12637
13322
|
function createSSEManager() {
|
|
@@ -12725,7 +13410,7 @@ __name(isBun, "isBun");
|
|
|
12725
13410
|
|
|
12726
13411
|
// core/server/server.ts
|
|
12727
13412
|
function createServer(config) {
|
|
12728
|
-
const app = new
|
|
13413
|
+
const app = new Hono3();
|
|
12729
13414
|
const sseManager = createSSEManager();
|
|
12730
13415
|
if (config.enableCors !== false) {
|
|
12731
13416
|
app.use("*", cors({
|
|
@@ -12749,11 +13434,18 @@ function createServer(config) {
|
|
|
12749
13434
|
ideas: "/api/ideas",
|
|
12750
13435
|
roadmap: "/api/roadmap",
|
|
12751
13436
|
shipped: "/api/shipped",
|
|
12752
|
-
events: "/api/events"
|
|
13437
|
+
events: "/api/events",
|
|
13438
|
+
// Extended endpoints for status-bar
|
|
13439
|
+
projects: "/api/projects",
|
|
13440
|
+
projectFull: "/api/projects/:id/full",
|
|
13441
|
+
statusBarCompact: "/api/status-bar/compact",
|
|
13442
|
+
globalStats: "/api/stats/global"
|
|
12753
13443
|
}
|
|
12754
13444
|
}));
|
|
12755
13445
|
const routes = createRoutes(config.projectId, config.projectPath);
|
|
12756
13446
|
app.route("/api", routes);
|
|
13447
|
+
const extendedRoutes = createExtendedRoutes();
|
|
13448
|
+
app.route("/api", extendedRoutes);
|
|
12757
13449
|
app.get("/api/events", (c) => {
|
|
12758
13450
|
return sseManager.handleConnection(c);
|
|
12759
13451
|
});
|