prjct-cli 1.22.0 → 1.24.0
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 +230 -0
- package/bin/prjct +30 -13
- package/dist/bin/prjct-core.mjs +1748 -0
- package/dist/bin/prjct.mjs +17 -36672
- package/dist/cli/linear.mjs +14 -0
- package/dist/daemon/entry.mjs +1429 -0
- package/dist/templates.json +1 -0
- package/package.json +4 -5
- package/bin/prjct.ts +0 -342
- package/core/__tests__/agentic/analysis-injection.test.ts +0 -377
- package/core/__tests__/agentic/cache-eviction.test.ts +0 -294
- package/core/__tests__/agentic/command-context.test.ts +0 -281
- package/core/__tests__/agentic/command-executor.test.ts +0 -659
- package/core/__tests__/agentic/domain-classifier.test.ts +0 -330
- package/core/__tests__/agentic/injection-validator.test.ts +0 -255
- package/core/__tests__/agentic/memory-system.test.ts +0 -281
- package/core/__tests__/agentic/plan-mode.test.ts +0 -386
- package/core/__tests__/agentic/prompt-assembly.test.ts +0 -298
- package/core/__tests__/agentic/prompt-builder.test.ts +0 -243
- package/core/__tests__/agentic/response-validator.test.ts +0 -263
- package/core/__tests__/agentic/semantic-matching.test.ts +0 -131
- package/core/__tests__/agentic/smart-context.test.ts +0 -372
- package/core/__tests__/agentic/tech-normalizer.test.ts +0 -136
- package/core/__tests__/agentic/token-budget.test.ts +0 -294
- package/core/__tests__/ai-tools/formatters.test.ts +0 -476
- package/core/__tests__/domain/bm25.test.ts +0 -225
- package/core/__tests__/domain/change-propagator.test.ts +0 -100
- package/core/__tests__/domain/fibonacci.test.ts +0 -113
- package/core/__tests__/domain/file-hasher.test.ts +0 -146
- package/core/__tests__/domain/file-ranker.test.ts +0 -169
- package/core/__tests__/domain/git-cochange.test.ts +0 -121
- package/core/__tests__/domain/import-graph.test.ts +0 -156
- package/core/__tests__/domain/velocity.test.ts +0 -623
- package/core/__tests__/infrastructure/performance-tracker.test.ts +0 -328
- package/core/__tests__/schemas/model.test.ts +0 -272
- package/core/__tests__/services/dependency-validator.test.ts +0 -175
- package/core/__tests__/services/hierarchical-agent-resolver.test.ts +0 -359
- package/core/__tests__/services/nested-context-resolver.test.ts +0 -443
- package/core/__tests__/services/project-index.test.ts +0 -355
- package/core/__tests__/services/staleness-checker.test.ts +0 -204
- package/core/__tests__/storage/analysis-storage.test.ts +0 -641
- package/core/__tests__/storage/archive-storage.test.ts +0 -455
- package/core/__tests__/storage/safe-reader.test.ts +0 -262
- package/core/__tests__/storage/sqlite-migration.test.ts +0 -1016
- package/core/__tests__/storage/state-storage-feedback.test.ts +0 -463
- package/core/__tests__/storage/state-storage-history.test.ts +0 -469
- package/core/__tests__/storage/storage-manager.test.ts +0 -383
- package/core/__tests__/storage/subtask-handoff.test.ts +0 -237
- package/core/__tests__/types/fs.test.ts +0 -125
- package/core/__tests__/utils/date-helper.test.ts +0 -449
- package/core/__tests__/utils/output.test.ts +0 -278
- package/core/__tests__/utils/preserve-sections.test.ts +0 -216
- package/core/__tests__/utils/project-commands.test.ts +0 -71
- package/core/__tests__/utils/retry.test.ts +0 -381
- package/core/__tests__/workflow/state-machine.test.ts +0 -216
- package/core/agentic/agent-router.ts +0 -150
- package/core/agentic/anti-hallucination.ts +0 -141
- package/core/agentic/chain-of-thought.ts +0 -234
- package/core/agentic/command-classifier.ts +0 -141
- package/core/agentic/command-context.ts +0 -168
- package/core/agentic/command-executor.ts +0 -471
- package/core/agentic/context-builder.ts +0 -285
- package/core/agentic/domain-classifier.ts +0 -525
- package/core/agentic/environment-block.ts +0 -102
- package/core/agentic/ground-truth.ts +0 -706
- package/core/agentic/index.ts +0 -193
- package/core/agentic/injection-validator.ts +0 -208
- package/core/agentic/loop-detector.ts +0 -451
- package/core/agentic/memory-system.ts +0 -1547
- package/core/agentic/orchestrator-executor.ts +0 -579
- package/core/agentic/plan-mode.ts +0 -525
- package/core/agentic/prompt-builder.ts +0 -1069
- package/core/agentic/response-validator.ts +0 -98
- package/core/agentic/services.ts +0 -167
- package/core/agentic/skill-loader.ts +0 -106
- package/core/agentic/smart-context.ts +0 -393
- package/core/agentic/tech-normalizer.ts +0 -167
- package/core/agentic/template-executor.ts +0 -272
- package/core/agentic/template-loader.ts +0 -109
- package/core/agentic/token-budget.ts +0 -226
- package/core/agentic/tool-registry.ts +0 -146
- package/core/agents/index.ts +0 -28
- package/core/agents/performance.ts +0 -429
- package/core/ai-tools/formatters.ts +0 -341
- package/core/ai-tools/generator.ts +0 -144
- package/core/ai-tools/index.ts +0 -15
- package/core/ai-tools/registry.ts +0 -201
- package/core/bus/bus.ts +0 -314
- package/core/bus/index.ts +0 -8
- package/core/cli/linear.ts +0 -500
- package/core/cli/lint-meta-commentary.ts +0 -177
- package/core/cli/start.ts +0 -386
- package/core/commands/analysis.ts +0 -1274
- package/core/commands/analytics.ts +0 -342
- package/core/commands/base.ts +0 -118
- package/core/commands/cleanup.ts +0 -157
- package/core/commands/command-data.ts +0 -463
- package/core/commands/commands.ts +0 -306
- package/core/commands/context.ts +0 -238
- package/core/commands/design.ts +0 -77
- package/core/commands/index.ts +0 -19
- package/core/commands/maintenance.ts +0 -77
- package/core/commands/performance.ts +0 -114
- package/core/commands/planning.ts +0 -662
- package/core/commands/register.ts +0 -127
- package/core/commands/registry.ts +0 -444
- package/core/commands/setup.ts +0 -280
- package/core/commands/shipping.ts +0 -267
- package/core/commands/snapshots.ts +0 -297
- package/core/commands/uninstall.ts +0 -542
- package/core/commands/velocity.ts +0 -149
- package/core/commands/workflow.ts +0 -505
- package/core/config/command-context.config.json +0 -66
- package/core/constants/index.ts +0 -379
- package/core/context/generator.ts +0 -368
- package/core/context-tools/files-tool.ts +0 -577
- package/core/context-tools/imports-tool.ts +0 -400
- package/core/context-tools/index.ts +0 -434
- package/core/context-tools/recent-tool.ts +0 -301
- package/core/context-tools/signatures-tool.ts +0 -495
- package/core/context-tools/summary-tool.ts +0 -301
- package/core/context-tools/token-counter.ts +0 -273
- package/core/context-tools/types.ts +0 -253
- package/core/domain/agent-generator.ts +0 -186
- package/core/domain/agent-loader.ts +0 -419
- package/core/domain/analyzer.ts +0 -387
- package/core/domain/architecture-generator.ts +0 -108
- package/core/domain/bm25.ts +0 -525
- package/core/domain/change-propagator.ts +0 -162
- package/core/domain/context-estimator.ts +0 -175
- package/core/domain/fibonacci.ts +0 -128
- package/core/domain/file-hasher.ts +0 -296
- package/core/domain/file-ranker.ts +0 -151
- package/core/domain/git-cochange.ts +0 -250
- package/core/domain/import-graph.ts +0 -315
- package/core/domain/snapshot-manager.ts +0 -415
- package/core/domain/task-stack.ts +0 -578
- package/core/domain/velocity.ts +0 -470
- package/core/errors.ts +0 -335
- package/core/events/events.ts +0 -85
- package/core/events/index.ts +0 -8
- package/core/index.ts +0 -481
- package/core/infrastructure/agent-detector.ts +0 -135
- package/core/infrastructure/ai-provider.ts +0 -578
- package/core/infrastructure/author-detector.ts +0 -133
- package/core/infrastructure/capability-installer.ts +0 -76
- package/core/infrastructure/claude-agent.ts +0 -297
- package/core/infrastructure/command-installer.ts +0 -752
- package/core/infrastructure/config-manager.ts +0 -364
- package/core/infrastructure/editors-config.ts +0 -172
- package/core/infrastructure/path-manager.ts +0 -571
- package/core/infrastructure/performance-tracker.ts +0 -326
- package/core/infrastructure/permission-manager.ts +0 -289
- package/core/infrastructure/setup.ts +0 -1061
- package/core/infrastructure/update-checker.ts +0 -246
- package/core/integrations/issue-tracker/enricher.ts +0 -271
- package/core/integrations/issue-tracker/index.ts +0 -8
- package/core/integrations/issue-tracker/manager.ts +0 -286
- package/core/integrations/issue-tracker/types.ts +0 -310
- package/core/integrations/jira/cache.ts +0 -57
- package/core/integrations/jira/client.ts +0 -688
- package/core/integrations/jira/index.ts +0 -23
- package/core/integrations/jira/service.ts +0 -244
- package/core/integrations/linear/cache.ts +0 -68
- package/core/integrations/linear/client.ts +0 -436
- package/core/integrations/linear/index.ts +0 -20
- package/core/integrations/linear/service.ts +0 -260
- package/core/integrations/linear/sync.ts +0 -314
- package/core/outcomes/analyzer.ts +0 -286
- package/core/outcomes/index.ts +0 -34
- package/core/outcomes/recorder.ts +0 -195
- package/core/plugin/builtin/webhook.ts +0 -148
- package/core/plugin/hooks.ts +0 -315
- package/core/plugin/index.ts +0 -50
- package/core/plugin/loader.ts +0 -354
- package/core/plugin/registry.ts +0 -326
- package/core/schemas/agents.ts +0 -27
- package/core/schemas/analysis.ts +0 -530
- package/core/schemas/classification.ts +0 -91
- package/core/schemas/command-context.ts +0 -29
- package/core/schemas/enriched-task.ts +0 -291
- package/core/schemas/ideas.ts +0 -114
- package/core/schemas/index.ts +0 -53
- package/core/schemas/issues.ts +0 -159
- package/core/schemas/llm-output.ts +0 -170
- package/core/schemas/metrics.ts +0 -143
- package/core/schemas/model.ts +0 -153
- package/core/schemas/outcomes.ts +0 -487
- package/core/schemas/performance.ts +0 -128
- package/core/schemas/permissions.ts +0 -180
- package/core/schemas/prd.ts +0 -450
- package/core/schemas/project.ts +0 -57
- package/core/schemas/roadmap.ts +0 -322
- package/core/schemas/schemas.ts +0 -38
- package/core/schemas/shipped.ts +0 -109
- package/core/schemas/state.ts +0 -284
- package/core/schemas/velocity.ts +0 -103
- package/core/server/index.ts +0 -21
- package/core/server/routes-extended.ts +0 -566
- package/core/server/routes.ts +0 -176
- package/core/server/server.ts +0 -149
- package/core/server/sse.ts +0 -192
- package/core/services/agent-generator.ts +0 -385
- package/core/services/agent-service.ts +0 -168
- package/core/services/breakdown-service.ts +0 -124
- package/core/services/context-generator.ts +0 -445
- package/core/services/context-selector.ts +0 -429
- package/core/services/dependency-validator.ts +0 -318
- package/core/services/diff-generator.ts +0 -313
- package/core/services/doctor-service.ts +0 -423
- package/core/services/file-categorizer.ts +0 -448
- package/core/services/file-scorer.ts +0 -270
- package/core/services/git-analyzer.ts +0 -293
- package/core/services/hierarchical-agent-resolver.ts +0 -236
- package/core/services/hooks-service.ts +0 -685
- package/core/services/index.ts +0 -46
- package/core/services/local-state-generator.ts +0 -158
- package/core/services/memory-service.ts +0 -181
- package/core/services/nested-context-resolver.ts +0 -842
- package/core/services/project-index.ts +0 -911
- package/core/services/project-service.ts +0 -155
- package/core/services/session-tracker.ts +0 -287
- package/core/services/skill-installer.ts +0 -447
- package/core/services/skill-lock.ts +0 -132
- package/core/services/skill-service.ts +0 -306
- package/core/services/stack-detector.ts +0 -229
- package/core/services/staleness-checker.ts +0 -327
- package/core/services/sync-service.ts +0 -1515
- package/core/services/sync-verifier.ts +0 -253
- package/core/services/watch-service.ts +0 -312
- package/core/session/compaction.ts +0 -248
- package/core/session/index.ts +0 -35
- package/core/session/log-migration.ts +0 -88
- package/core/session/metrics.ts +0 -323
- package/core/session/session-log-manager.ts +0 -307
- package/core/session/task-session-manager.ts +0 -404
- package/core/session/utils.ts +0 -51
- package/core/storage/analysis-storage.ts +0 -373
- package/core/storage/archive-storage.ts +0 -205
- package/core/storage/database.ts +0 -575
- package/core/storage/ideas-storage.ts +0 -298
- package/core/storage/index-storage.ts +0 -523
- package/core/storage/index.ts +0 -79
- package/core/storage/metrics-storage.ts +0 -321
- package/core/storage/migrate-json.ts +0 -720
- package/core/storage/queue-storage.ts +0 -336
- package/core/storage/safe-reader.ts +0 -105
- package/core/storage/shipped-storage.ts +0 -253
- package/core/storage/state-storage.ts +0 -1035
- package/core/storage/storage-manager.ts +0 -205
- package/core/storage/storage.ts +0 -177
- package/core/storage/velocity-storage.ts +0 -149
- package/core/sync/auth-config.ts +0 -138
- package/core/sync/index.ts +0 -31
- package/core/sync/oauth-handler.ts +0 -143
- package/core/sync/sync-client.ts +0 -251
- package/core/sync/sync-manager.ts +0 -327
- package/core/tsconfig.json +0 -22
- package/core/types/agentic.ts +0 -760
- package/core/types/agents.ts +0 -150
- package/core/types/bus.ts +0 -193
- package/core/types/citations.ts +0 -22
- package/core/types/commands.ts +0 -399
- package/core/types/config.ts +0 -92
- package/core/types/core.ts +0 -96
- package/core/types/diff.ts +0 -41
- package/core/types/domain.ts +0 -71
- package/core/types/errors.ts +0 -111
- package/core/types/events.ts +0 -42
- package/core/types/fs.ts +0 -72
- package/core/types/index.ts +0 -510
- package/core/types/infrastructure.ts +0 -210
- package/core/types/integrations.ts +0 -31
- package/core/types/jira.ts +0 -51
- package/core/types/logger.ts +0 -17
- package/core/types/memory.ts +0 -313
- package/core/types/outcomes.ts +0 -190
- package/core/types/output.ts +0 -47
- package/core/types/plugin.ts +0 -25
- package/core/types/project-sync.ts +0 -129
- package/core/types/provider.ts +0 -163
- package/core/types/server.ts +0 -71
- package/core/types/services.ts +0 -84
- package/core/types/session.ts +0 -135
- package/core/types/stack.ts +0 -19
- package/core/types/storage.ts +0 -318
- package/core/types/sync-verifier.ts +0 -33
- package/core/types/sync.ts +0 -121
- package/core/types/task.ts +0 -72
- package/core/types/template.ts +0 -24
- package/core/types/utils.ts +0 -92
- package/core/types/workflow.ts +0 -23
- package/core/utils/agent-stream.ts +0 -140
- package/core/utils/animations.ts +0 -251
- package/core/utils/branding.ts +0 -88
- package/core/utils/cache.ts +0 -187
- package/core/utils/citations.ts +0 -39
- package/core/utils/collection-filters.ts +0 -209
- package/core/utils/date-helper.ts +0 -176
- package/core/utils/error-messages.ts +0 -38
- package/core/utils/file-helper.ts +0 -277
- package/core/utils/fs-helpers.ts +0 -14
- package/core/utils/help.ts +0 -314
- package/core/utils/jsonl-helper.ts +0 -290
- package/core/utils/keychain.ts +0 -127
- package/core/utils/logger.ts +0 -77
- package/core/utils/markdown-builder.ts +0 -280
- package/core/utils/next-steps.ts +0 -95
- package/core/utils/output.ts +0 -403
- package/core/utils/preserve-sections.ts +0 -218
- package/core/utils/project-commands.ts +0 -126
- package/core/utils/project-credentials.ts +0 -143
- package/core/utils/provider-cache.ts +0 -49
- package/core/utils/retry.ts +0 -318
- package/core/utils/runtime.ts +0 -108
- package/core/utils/session-helper.ts +0 -278
- package/core/utils/subtask-table.ts +0 -227
- package/core/utils/version.ts +0 -128
- package/core/wizard/index.ts +0 -13
- package/core/wizard/onboarding.ts +0 -633
- package/core/workflow/index.ts +0 -7
- package/core/workflow/state-machine.ts +0 -198
- package/core/workflow/workflow-preferences.ts +0 -294
- package/dist/core/infrastructure/command-installer.js +0 -1141
- package/dist/core/infrastructure/editors-config.js +0 -177
- package/dist/core/infrastructure/setup.js +0 -2244
- package/dist/core/utils/version.js +0 -141
- package/templates/agentic/agent-routing.md +0 -45
- package/templates/agentic/agents/uxui.md +0 -63
- package/templates/agentic/checklist-routing.md +0 -98
- package/templates/agentic/orchestrator.md +0 -68
- package/templates/agentic/task-fragmentation.md +0 -89
- package/templates/agents/AGENTS.md +0 -68
- package/templates/analysis/analyze.md +0 -84
- package/templates/analysis/patterns.md +0 -60
- package/templates/antigravity/SKILL.md +0 -39
- package/templates/architect/discovery.md +0 -67
- package/templates/architect/phases.md +0 -59
- package/templates/checklists/architecture.md +0 -28
- package/templates/checklists/code-quality.md +0 -28
- package/templates/checklists/data.md +0 -33
- package/templates/checklists/documentation.md +0 -33
- package/templates/checklists/infrastructure.md +0 -33
- package/templates/checklists/performance.md +0 -33
- package/templates/checklists/security.md +0 -33
- package/templates/checklists/testing.md +0 -33
- package/templates/checklists/ux-ui.md +0 -37
- package/templates/commands/analyze.md +0 -56
- package/templates/commands/auth.md +0 -234
- package/templates/commands/bug.md +0 -163
- package/templates/commands/cleanup.md +0 -19
- package/templates/commands/dash.md +0 -99
- package/templates/commands/design.md +0 -15
- package/templates/commands/done.md +0 -291
- package/templates/commands/enrich.md +0 -174
- package/templates/commands/git.md +0 -295
- package/templates/commands/history.md +0 -389
- package/templates/commands/idea.md +0 -88
- package/templates/commands/impact.md +0 -864
- package/templates/commands/init.md +0 -54
- package/templates/commands/jira.md +0 -278
- package/templates/commands/linear.md +0 -288
- package/templates/commands/merge.md +0 -206
- package/templates/commands/next.md +0 -80
- package/templates/commands/p.md +0 -67
- package/templates/commands/p.toml +0 -37
- package/templates/commands/pause.md +0 -136
- package/templates/commands/plan.md +0 -696
- package/templates/commands/prd.md +0 -356
- package/templates/commands/resume.md +0 -171
- package/templates/commands/review.md +0 -276
- package/templates/commands/serve.md +0 -118
- package/templates/commands/setup.md +0 -91
- package/templates/commands/ship.md +0 -475
- package/templates/commands/skill.md +0 -259
- package/templates/commands/spec.md +0 -218
- package/templates/commands/status.md +0 -207
- package/templates/commands/sync.md +0 -104
- package/templates/commands/task.md +0 -312
- package/templates/commands/test.md +0 -93
- package/templates/commands/update.md +0 -63
- package/templates/commands/verify.md +0 -204
- package/templates/commands/workflow.md +0 -150
- package/templates/config/skill-mappings.json +0 -82
- package/templates/context/dashboard.md +0 -256
- package/templates/context/roadmap.md +0 -221
- package/templates/cursor/commands/bug.md +0 -8
- package/templates/cursor/commands/done.md +0 -4
- package/templates/cursor/commands/pause.md +0 -6
- package/templates/cursor/commands/resume.md +0 -4
- package/templates/cursor/commands/ship.md +0 -8
- package/templates/cursor/commands/sync.md +0 -4
- package/templates/cursor/commands/task.md +0 -8
- package/templates/cursor/p.md +0 -29
- package/templates/cursor/router.mdc +0 -28
- package/templates/design/api.md +0 -95
- package/templates/design/architecture.md +0 -77
- package/templates/design/component.md +0 -89
- package/templates/design/database.md +0 -78
- package/templates/design/flow.md +0 -94
- package/templates/global/ANTIGRAVITY.md +0 -254
- package/templates/global/CLAUDE.md +0 -497
- package/templates/global/CURSOR.mdc +0 -266
- package/templates/global/GEMINI.md +0 -293
- package/templates/global/STORAGE-SPEC.md +0 -391
- package/templates/global/WINDSURF.md +0 -266
- package/templates/global/modules/CLAUDE-commands.md +0 -70
- package/templates/global/modules/CLAUDE-core.md +0 -105
- package/templates/global/modules/CLAUDE-git.md +0 -50
- package/templates/global/modules/CLAUDE-intelligence.md +0 -92
- package/templates/global/modules/CLAUDE-storage.md +0 -50
- package/templates/global/modules/module-config.json +0 -36
- package/templates/mcp-config.json +0 -19
- package/templates/permissions/default.jsonc +0 -60
- package/templates/permissions/permissive.jsonc +0 -49
- package/templates/permissions/strict.jsonc +0 -58
- package/templates/planning-methodology.md +0 -195
- package/templates/skills/code-review.md +0 -47
- package/templates/skills/debug.md +0 -61
- package/templates/skills/refactor.md +0 -47
- package/templates/subagents/agent-base.md +0 -20
- package/templates/subagents/domain/backend.md +0 -109
- package/templates/subagents/domain/database.md +0 -121
- package/templates/subagents/domain/devops.md +0 -152
- package/templates/subagents/domain/frontend.md +0 -103
- package/templates/subagents/domain/testing.md +0 -169
- package/templates/subagents/pm-expert.md +0 -366
- package/templates/subagents/workflow/chief-architect.md +0 -657
- package/templates/subagents/workflow/prjct-planner.md +0 -159
- package/templates/subagents/workflow/prjct-shipper.md +0 -188
- package/templates/subagents/workflow/prjct-workflow.md +0 -98
- package/templates/tools/bash.txt +0 -22
- package/templates/tools/edit.txt +0 -18
- package/templates/tools/glob.txt +0 -19
- package/templates/tools/grep.txt +0 -21
- package/templates/tools/read.txt +0 -14
- package/templates/tools/task.txt +0 -20
- package/templates/tools/webfetch.txt +0 -16
- package/templates/tools/websearch.txt +0 -18
- package/templates/tools/write.txt +0 -17
- package/templates/windsurf/router.md +0 -28
- package/templates/windsurf/workflows/bug.md +0 -8
- package/templates/windsurf/workflows/done.md +0 -4
- package/templates/windsurf/workflows/pause.md +0 -4
- package/templates/windsurf/workflows/resume.md +0 -4
- package/templates/windsurf/workflows/ship.md +0 -8
- package/templates/windsurf/workflows/sync.md +0 -4
- package/templates/windsurf/workflows/task.md +0 -8
package/core/cli/linear.ts
DELETED
|
@@ -1,500 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Linear CLI - Bridge between templates and SDK
|
|
5
|
-
*
|
|
6
|
-
* Usage: bun core/cli/linear.ts --project <projectId> <command> [args...]
|
|
7
|
-
*
|
|
8
|
-
* Flags:
|
|
9
|
-
* --project <id> - Project ID (required)
|
|
10
|
-
* --json - Output raw JSON (default: human-readable)
|
|
11
|
-
* --verbose - Show all details (no truncation)
|
|
12
|
-
*
|
|
13
|
-
* Commands:
|
|
14
|
-
* setup <apiKey> [teamId] - Store API key in project credentials
|
|
15
|
-
* list - List my assigned issues
|
|
16
|
-
* list-team <teamId> - List issues from a team
|
|
17
|
-
* get <id> - Get issue by ID or identifier (PRJ-123)
|
|
18
|
-
* get-local <id> - Get issue from local cache (no API call)
|
|
19
|
-
* sync - Pull all assigned issues to local storage
|
|
20
|
-
* sync-status - Check local cache status
|
|
21
|
-
* create <json> - Create issue from JSON input
|
|
22
|
-
* update <id> <json> - Update issue
|
|
23
|
-
* start <id> - Mark issue as in progress
|
|
24
|
-
* done <id> - Mark issue as done
|
|
25
|
-
* comment <id> <text> - Add comment to issue
|
|
26
|
-
* teams - List available teams
|
|
27
|
-
* projects - List available projects
|
|
28
|
-
* status - Check connection status
|
|
29
|
-
*
|
|
30
|
-
* Default output is human-readable. Use --json for machine parsing.
|
|
31
|
-
*/
|
|
32
|
-
|
|
33
|
-
import type { CreateIssueInput, Issue } from '../integrations/issue-tracker/types'
|
|
34
|
-
import { linearService, linearSync } from '../integrations/linear'
|
|
35
|
-
import { getErrorMessage } from '../types/fs'
|
|
36
|
-
import { formatForHuman, setOutputTier } from '../utils/output'
|
|
37
|
-
import {
|
|
38
|
-
getCredentialSource,
|
|
39
|
-
getLinearApiKey,
|
|
40
|
-
getProjectCredentials,
|
|
41
|
-
setLinearCredentials,
|
|
42
|
-
} from '../utils/project-credentials'
|
|
43
|
-
|
|
44
|
-
// Parse arguments
|
|
45
|
-
const args = process.argv.slice(2)
|
|
46
|
-
|
|
47
|
-
// Extract --project flag
|
|
48
|
-
const projectIdx = args.indexOf('--project')
|
|
49
|
-
let projectId: string | null = null
|
|
50
|
-
if (projectIdx !== -1 && args[projectIdx + 1]) {
|
|
51
|
-
projectId = args[projectIdx + 1]
|
|
52
|
-
args.splice(projectIdx, 2)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Extract --json flag (raw JSON output)
|
|
56
|
-
const jsonIdx = args.indexOf('--json')
|
|
57
|
-
const jsonMode = jsonIdx !== -1
|
|
58
|
-
if (jsonMode) args.splice(jsonIdx, 1)
|
|
59
|
-
|
|
60
|
-
// Extract --verbose flag
|
|
61
|
-
const verboseIdx = args.indexOf('--verbose')
|
|
62
|
-
const verboseMode = verboseIdx !== -1
|
|
63
|
-
if (verboseMode) {
|
|
64
|
-
args.splice(verboseIdx, 1)
|
|
65
|
-
setOutputTier('verbose')
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const [command, ...commandArgs] = args
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Output result - human-readable by default, JSON with --json flag
|
|
72
|
-
*/
|
|
73
|
-
function output(data: unknown): void {
|
|
74
|
-
if (jsonMode) {
|
|
75
|
-
console.log(JSON.stringify(data, null, 2))
|
|
76
|
-
} else {
|
|
77
|
-
console.log(formatForHuman(data))
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Output error and exit
|
|
83
|
-
*/
|
|
84
|
-
function error(message: string, code = 1): never {
|
|
85
|
-
if (jsonMode) {
|
|
86
|
-
console.error(JSON.stringify({ error: message }))
|
|
87
|
-
} else {
|
|
88
|
-
console.error(`Error: ${message}`)
|
|
89
|
-
}
|
|
90
|
-
process.exit(code)
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Initialize Linear service from project credentials
|
|
95
|
-
*/
|
|
96
|
-
async function initFromProject(): Promise<void> {
|
|
97
|
-
if (!projectId) {
|
|
98
|
-
error('No --project specified. Usage: linear.ts --project <projectId> <command>')
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const apiKey = await getLinearApiKey(projectId)
|
|
102
|
-
if (!apiKey) {
|
|
103
|
-
error('Linear not configured. Run: p. linear setup')
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const creds = await getProjectCredentials(projectId)
|
|
107
|
-
await linearService.initializeFromApiKey(apiKey, creds.linear?.teamId)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Main CLI handler
|
|
112
|
-
*/
|
|
113
|
-
async function main(): Promise<void> {
|
|
114
|
-
try {
|
|
115
|
-
switch (command) {
|
|
116
|
-
case 'setup': {
|
|
117
|
-
if (!projectId) {
|
|
118
|
-
error('--project required for setup')
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const apiKey = commandArgs[0]
|
|
122
|
-
const teamId = commandArgs[1] // optional
|
|
123
|
-
|
|
124
|
-
if (!apiKey) {
|
|
125
|
-
error('API key required. Usage: setup <apiKey> [teamId]')
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// Test connection first
|
|
129
|
-
await linearService.initializeFromApiKey(apiKey, teamId)
|
|
130
|
-
const teams = await linearService.getTeams()
|
|
131
|
-
|
|
132
|
-
if (teams.length === 0) {
|
|
133
|
-
error('No teams found. Check your API key permissions.')
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Determine default team
|
|
137
|
-
let selectedTeamId = teamId
|
|
138
|
-
let selectedTeamKey: string | undefined
|
|
139
|
-
|
|
140
|
-
if (!selectedTeamId && teams.length === 1) {
|
|
141
|
-
selectedTeamId = teams[0].id
|
|
142
|
-
selectedTeamKey = teams[0].key
|
|
143
|
-
} else if (selectedTeamId) {
|
|
144
|
-
const team = teams.find((t) => t.id === selectedTeamId || t.key === selectedTeamId)
|
|
145
|
-
if (team) {
|
|
146
|
-
selectedTeamId = team.id
|
|
147
|
-
selectedTeamKey = team.key
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// Store in project credentials
|
|
152
|
-
await setLinearCredentials(projectId, {
|
|
153
|
-
apiKey,
|
|
154
|
-
teamId: selectedTeamId,
|
|
155
|
-
teamKey: selectedTeamKey,
|
|
156
|
-
setupAt: new Date().toISOString(),
|
|
157
|
-
})
|
|
158
|
-
|
|
159
|
-
output({
|
|
160
|
-
success: true,
|
|
161
|
-
teams,
|
|
162
|
-
defaultTeam: selectedTeamId ? { id: selectedTeamId, key: selectedTeamKey } : null,
|
|
163
|
-
})
|
|
164
|
-
break
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
case 'list': {
|
|
168
|
-
await initFromProject()
|
|
169
|
-
const limit = commandArgs[0] ? parseInt(commandArgs[0], 10) : 20
|
|
170
|
-
|
|
171
|
-
// Use team issues if teamId is configured, otherwise assigned issues
|
|
172
|
-
const creds = await getProjectCredentials(projectId!)
|
|
173
|
-
let issues: Issue[]
|
|
174
|
-
if (creds.linear?.teamId) {
|
|
175
|
-
issues = await linearService.fetchTeamIssues(creds.linear.teamId, { limit })
|
|
176
|
-
} else {
|
|
177
|
-
issues = await linearService.fetchAssignedIssues({ limit })
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
const issueList = issues.map((issue) => ({
|
|
181
|
-
id: issue.id,
|
|
182
|
-
identifier: issue.externalId,
|
|
183
|
-
title: issue.title,
|
|
184
|
-
status: issue.status,
|
|
185
|
-
priority: issue.priority,
|
|
186
|
-
url: issue.url,
|
|
187
|
-
}))
|
|
188
|
-
|
|
189
|
-
if (jsonMode) {
|
|
190
|
-
output({ count: issues.length, issues: issueList })
|
|
191
|
-
} else {
|
|
192
|
-
// Human-friendly table output
|
|
193
|
-
console.log(`Your issues (${issues.length}):`)
|
|
194
|
-
for (const issue of issueList.slice(0, 10)) {
|
|
195
|
-
const p = issue.priority && issue.priority !== 'none' ? ` [${issue.priority}]` : ''
|
|
196
|
-
console.log(` ${issue.identifier} ${issue.title.slice(0, 50)}${p}`)
|
|
197
|
-
}
|
|
198
|
-
if (issues.length > 10) {
|
|
199
|
-
console.log(` ...${issues.length - 10} more`)
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
break
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
case 'list-team': {
|
|
206
|
-
await initFromProject()
|
|
207
|
-
const teamId = commandArgs[0]
|
|
208
|
-
const limit = commandArgs[1] ? parseInt(commandArgs[1], 10) : 20
|
|
209
|
-
|
|
210
|
-
if (!teamId) {
|
|
211
|
-
error('Team ID required. Usage: list-team <teamId> [limit]')
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
const issues = await linearService.fetchTeamIssues(teamId, { limit })
|
|
215
|
-
output({
|
|
216
|
-
count: issues.length,
|
|
217
|
-
issues: issues.map((issue) => ({
|
|
218
|
-
id: issue.id,
|
|
219
|
-
identifier: issue.externalId,
|
|
220
|
-
title: issue.title,
|
|
221
|
-
status: issue.status,
|
|
222
|
-
priority: issue.priority,
|
|
223
|
-
url: issue.url,
|
|
224
|
-
})),
|
|
225
|
-
})
|
|
226
|
-
break
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
case 'get': {
|
|
230
|
-
await initFromProject()
|
|
231
|
-
const id = commandArgs[0]
|
|
232
|
-
|
|
233
|
-
if (!id) {
|
|
234
|
-
error('Issue ID required. Usage: get <id>')
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
const issue = await linearService.fetchIssue(id)
|
|
238
|
-
if (!issue) {
|
|
239
|
-
error(`Issue not found: ${id}`)
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
if (jsonMode) {
|
|
243
|
-
output(issue)
|
|
244
|
-
} else {
|
|
245
|
-
// Human-friendly issue display
|
|
246
|
-
console.log(`${issue.externalId}: ${issue.title}`)
|
|
247
|
-
console.log(`Status: ${issue.status} | Priority: ${issue.priority || 'none'}`)
|
|
248
|
-
if (issue.description) {
|
|
249
|
-
const desc = issue.description.slice(0, 200)
|
|
250
|
-
console.log(`\n${desc}${issue.description.length > 200 ? '...' : ''}`)
|
|
251
|
-
}
|
|
252
|
-
console.log(`\n${issue.url}`)
|
|
253
|
-
}
|
|
254
|
-
break
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
case 'get-local': {
|
|
258
|
-
if (!projectId) {
|
|
259
|
-
error('--project required for get-local')
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
const id = commandArgs[0]
|
|
263
|
-
if (!id) {
|
|
264
|
-
error('Issue ID required. Usage: get-local <id>')
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
const cachedIssue = await linearSync.getIssueLocal(projectId, id)
|
|
268
|
-
if (!cachedIssue) {
|
|
269
|
-
error(`Issue not in local cache: ${id}. Run 'sync' first.`)
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
output(cachedIssue)
|
|
273
|
-
break
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
case 'sync': {
|
|
277
|
-
if (!projectId) {
|
|
278
|
-
error('--project required for sync')
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
await initFromProject()
|
|
282
|
-
const result = await linearSync.pullAll(projectId)
|
|
283
|
-
|
|
284
|
-
output({
|
|
285
|
-
success: result.errors.length === 0,
|
|
286
|
-
...result,
|
|
287
|
-
})
|
|
288
|
-
break
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
case 'sync-status': {
|
|
292
|
-
if (!projectId) {
|
|
293
|
-
error('--project required for sync-status')
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
const status = await linearSync.getSyncStatus(projectId)
|
|
297
|
-
output(status)
|
|
298
|
-
break
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
case 'create': {
|
|
302
|
-
await initFromProject()
|
|
303
|
-
const inputJson = commandArgs[0]
|
|
304
|
-
|
|
305
|
-
if (!inputJson) {
|
|
306
|
-
error('JSON input required. Usage: create \'{"title":"...", "teamId":"..."}\'')
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
let input: Record<string, unknown>
|
|
310
|
-
try {
|
|
311
|
-
input = JSON.parse(inputJson)
|
|
312
|
-
} catch {
|
|
313
|
-
error(`Invalid JSON: ${inputJson}`)
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
if (!input.title) {
|
|
317
|
-
error('title is required')
|
|
318
|
-
}
|
|
319
|
-
if (!input.teamId) {
|
|
320
|
-
// Try to use default team from credentials
|
|
321
|
-
const creds = await getProjectCredentials(projectId!)
|
|
322
|
-
if (creds.linear?.teamId) {
|
|
323
|
-
input.teamId = creds.linear.teamId
|
|
324
|
-
} else {
|
|
325
|
-
error('teamId is required (no default team configured)')
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
const issue = await linearService.createIssue(input as unknown as CreateIssueInput)
|
|
330
|
-
output(issue)
|
|
331
|
-
break
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
case 'update': {
|
|
335
|
-
await initFromProject()
|
|
336
|
-
const id = commandArgs[0]
|
|
337
|
-
const inputJson = commandArgs[1]
|
|
338
|
-
|
|
339
|
-
if (!id) {
|
|
340
|
-
error('Issue ID required. Usage: update <id> \'{"description":"..."}\'')
|
|
341
|
-
}
|
|
342
|
-
if (!inputJson) {
|
|
343
|
-
error('JSON input required. Usage: update <id> \'{"description":"..."}\'')
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
let input: Record<string, unknown>
|
|
347
|
-
try {
|
|
348
|
-
input = JSON.parse(inputJson)
|
|
349
|
-
} catch {
|
|
350
|
-
error(`Invalid JSON: ${inputJson}`)
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
const issue = await linearService.updateIssue(id, input)
|
|
354
|
-
output(issue)
|
|
355
|
-
break
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
case 'start': {
|
|
359
|
-
await initFromProject()
|
|
360
|
-
const id = commandArgs[0]
|
|
361
|
-
|
|
362
|
-
if (!id) {
|
|
363
|
-
error('Issue ID required. Usage: start <id>')
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
await linearService.markInProgress(id)
|
|
367
|
-
output({ success: true, id, status: 'in_progress' })
|
|
368
|
-
break
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
case 'done': {
|
|
372
|
-
await initFromProject()
|
|
373
|
-
const id = commandArgs[0]
|
|
374
|
-
|
|
375
|
-
if (!id) {
|
|
376
|
-
error('Issue ID required. Usage: done <id>')
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
await linearService.markDone(id)
|
|
380
|
-
output({ success: true, id, status: 'done' })
|
|
381
|
-
break
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
case 'comment': {
|
|
385
|
-
await initFromProject()
|
|
386
|
-
const id = commandArgs[0]
|
|
387
|
-
const body = commandArgs.slice(1).join(' ')
|
|
388
|
-
|
|
389
|
-
if (!id) {
|
|
390
|
-
error('Issue ID required. Usage: comment <id> <text>')
|
|
391
|
-
}
|
|
392
|
-
if (!body) {
|
|
393
|
-
error('Comment text required. Usage: comment <id> <text>')
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
await linearService.addComment(id, body)
|
|
397
|
-
output({ success: true, id })
|
|
398
|
-
break
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
case 'teams': {
|
|
402
|
-
await initFromProject()
|
|
403
|
-
const teams = await linearService.getTeams()
|
|
404
|
-
output({ count: teams.length, teams })
|
|
405
|
-
break
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
case 'projects': {
|
|
409
|
-
await initFromProject()
|
|
410
|
-
const projects = await linearService.getProjects()
|
|
411
|
-
output({ count: projects.length, projects })
|
|
412
|
-
break
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
case 'status': {
|
|
416
|
-
if (!projectId) {
|
|
417
|
-
error('--project required for status')
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
const source = await getCredentialSource(projectId)
|
|
421
|
-
const apiKey = await getLinearApiKey(projectId)
|
|
422
|
-
const creds = await getProjectCredentials(projectId)
|
|
423
|
-
|
|
424
|
-
if (!apiKey) {
|
|
425
|
-
if (jsonMode) {
|
|
426
|
-
output({ configured: false, source: 'none', message: 'Linear not configured' })
|
|
427
|
-
} else {
|
|
428
|
-
console.log('Linear: Not configured')
|
|
429
|
-
console.log('Run: p. linear setup')
|
|
430
|
-
}
|
|
431
|
-
break
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
// Test connection
|
|
435
|
-
try {
|
|
436
|
-
await linearService.initializeFromApiKey(apiKey, creds.linear?.teamId)
|
|
437
|
-
const teams = await linearService.getTeams()
|
|
438
|
-
|
|
439
|
-
if (jsonMode) {
|
|
440
|
-
output({
|
|
441
|
-
configured: true,
|
|
442
|
-
source,
|
|
443
|
-
teamId: creds.linear?.teamId,
|
|
444
|
-
teamKey: creds.linear?.teamKey,
|
|
445
|
-
teamsAvailable: teams.length,
|
|
446
|
-
})
|
|
447
|
-
} else {
|
|
448
|
-
console.log(`Linear: Connected`)
|
|
449
|
-
if (creds.linear?.teamKey) {
|
|
450
|
-
console.log(`Team: ${creds.linear.teamKey}`)
|
|
451
|
-
}
|
|
452
|
-
console.log(`Teams: ${teams.length} available`)
|
|
453
|
-
}
|
|
454
|
-
} catch (err) {
|
|
455
|
-
if (jsonMode) {
|
|
456
|
-
output({ configured: true, source, connectionError: getErrorMessage(err) })
|
|
457
|
-
} else {
|
|
458
|
-
console.log(`Linear: Connection error`)
|
|
459
|
-
console.log(`Error: ${getErrorMessage(err)}`)
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
break
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
case 'help':
|
|
466
|
-
case '--help':
|
|
467
|
-
case '-h':
|
|
468
|
-
case undefined: {
|
|
469
|
-
output({
|
|
470
|
-
usage: 'linear.ts --project <projectId> <command> [args...]',
|
|
471
|
-
commands: {
|
|
472
|
-
setup: 'setup <apiKey> [teamId] - Store API key',
|
|
473
|
-
list: 'list [limit] - List my assigned issues',
|
|
474
|
-
'list-team': 'list-team <teamId> [limit] - List team issues',
|
|
475
|
-
get: 'get <id> - Get issue by ID or identifier',
|
|
476
|
-
'get-local': 'get-local <id> - Get from local cache (no API)',
|
|
477
|
-
sync: 'sync - Pull all assigned issues to local storage',
|
|
478
|
-
'sync-status': 'sync-status - Check local cache status',
|
|
479
|
-
create: 'create <json> - Create issue',
|
|
480
|
-
update: 'update <id> <json> - Update issue',
|
|
481
|
-
start: 'start <id> - Mark as in progress',
|
|
482
|
-
done: 'done <id> - Mark as done',
|
|
483
|
-
comment: 'comment <id> <text> - Add comment',
|
|
484
|
-
teams: 'teams - List available teams',
|
|
485
|
-
projects: 'projects - List available projects',
|
|
486
|
-
status: 'status - Check connection',
|
|
487
|
-
},
|
|
488
|
-
})
|
|
489
|
-
break
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
default:
|
|
493
|
-
error(`Unknown command: ${command}. Use --help to see available commands.`)
|
|
494
|
-
}
|
|
495
|
-
} catch (err) {
|
|
496
|
-
error(getErrorMessage(err))
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
main()
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
/**
|
|
3
|
-
* Lint rule: no-meta-commentary
|
|
4
|
-
*
|
|
5
|
-
* Catches AI memory meta-commentary patterns that should be avoided.
|
|
6
|
-
* Preferences should be presented as facts, not as memories.
|
|
7
|
-
*
|
|
8
|
-
* Anti-patterns:
|
|
9
|
-
* - "I remember you prefer..."
|
|
10
|
-
* - "Based on your history..."
|
|
11
|
-
* - "I've learned that..."
|
|
12
|
-
* - "From previous sessions..."
|
|
13
|
-
*
|
|
14
|
-
* Correct pattern:
|
|
15
|
-
* - "Use TypeScript strict mode" (not "I remember you like strict mode")
|
|
16
|
-
*
|
|
17
|
-
* @see PRJ-103
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
import { readdir, readFile } from 'node:fs/promises'
|
|
21
|
-
import { join, relative } from 'node:path'
|
|
22
|
-
|
|
23
|
-
const META_COMMENTARY_PATTERNS = [
|
|
24
|
-
// Direct memory references
|
|
25
|
-
/\bI remember\b/gi,
|
|
26
|
-
/\bI recall\b/gi,
|
|
27
|
-
/\bI('ve| have) learned\b/gi,
|
|
28
|
-
|
|
29
|
-
// History references
|
|
30
|
-
/\bBased on (your |)history\b/gi,
|
|
31
|
-
/\bFrom previous (session|conversation)s?\b/gi,
|
|
32
|
-
/\bIn (the |)past,? you\b/gi,
|
|
33
|
-
|
|
34
|
-
// Preference meta-commentary
|
|
35
|
-
/\byou (usually|typically|always|often) prefer\b/gi,
|
|
36
|
-
/\byou mentioned (before|earlier|previously)\b/gi,
|
|
37
|
-
/\blast time you\b/gi,
|
|
38
|
-
|
|
39
|
-
// Section headers that expose memory mechanism
|
|
40
|
-
/\bLEARNED PATTERNS\b/g,
|
|
41
|
-
/\bRELEVANT MEMORIES\b/g,
|
|
42
|
-
/\bLearned Patterns\b/g,
|
|
43
|
-
/\bRelevant Memories\b/g,
|
|
44
|
-
]
|
|
45
|
-
|
|
46
|
-
// Files/directories to skip
|
|
47
|
-
const SKIP_PATTERNS = [
|
|
48
|
-
/node_modules/,
|
|
49
|
-
/\.git/,
|
|
50
|
-
/dist/,
|
|
51
|
-
/build/,
|
|
52
|
-
/coverage/,
|
|
53
|
-
/\.test\.ts$/,
|
|
54
|
-
/\.spec\.ts$/,
|
|
55
|
-
/lint-meta-commentary\.ts$/, // Skip self
|
|
56
|
-
/\/docs\//, // Skip documentation (describes features, not agent output)
|
|
57
|
-
]
|
|
58
|
-
|
|
59
|
-
// Only check these extensions
|
|
60
|
-
const INCLUDE_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.md']
|
|
61
|
-
|
|
62
|
-
interface Violation {
|
|
63
|
-
file: string
|
|
64
|
-
line: number
|
|
65
|
-
column: number
|
|
66
|
-
match: string
|
|
67
|
-
pattern: string
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
async function* walkDir(dir: string): AsyncGenerator<string> {
|
|
71
|
-
const entries = await readdir(dir, { withFileTypes: true })
|
|
72
|
-
|
|
73
|
-
for (const entry of entries) {
|
|
74
|
-
const fullPath = join(dir, entry.name)
|
|
75
|
-
|
|
76
|
-
if (SKIP_PATTERNS.some((p) => p.test(fullPath))) {
|
|
77
|
-
continue
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
if (entry.isDirectory()) {
|
|
81
|
-
yield* walkDir(fullPath)
|
|
82
|
-
} else if (entry.isFile() && INCLUDE_EXTENSIONS.some((ext) => entry.name.endsWith(ext))) {
|
|
83
|
-
yield fullPath
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
async function checkFile(filePath: string): Promise<Violation[]> {
|
|
89
|
-
const violations: Violation[] = []
|
|
90
|
-
const content = await readFile(filePath, 'utf-8')
|
|
91
|
-
const lines = content.split('\n')
|
|
92
|
-
|
|
93
|
-
for (let lineNum = 0; lineNum < lines.length; lineNum++) {
|
|
94
|
-
const line = lines[lineNum]
|
|
95
|
-
|
|
96
|
-
// Skip comments - we only care about string literals that become agent output
|
|
97
|
-
const trimmed = line.trim()
|
|
98
|
-
if (
|
|
99
|
-
trimmed.startsWith('//') || // Inline comments
|
|
100
|
-
trimmed.startsWith('*') || // JSDoc/block comments
|
|
101
|
-
trimmed.startsWith('/*') || // Block comment start
|
|
102
|
-
line.includes('Anti-pattern') || // Documentation
|
|
103
|
-
line.includes('@see') || // JSDoc refs
|
|
104
|
-
line.includes('@example') // JSDoc examples
|
|
105
|
-
) {
|
|
106
|
-
continue
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
for (const pattern of META_COMMENTARY_PATTERNS) {
|
|
110
|
-
// Reset lastIndex for global patterns
|
|
111
|
-
pattern.lastIndex = 0
|
|
112
|
-
|
|
113
|
-
let match: RegExpExecArray | null
|
|
114
|
-
while ((match = pattern.exec(line)) !== null) {
|
|
115
|
-
violations.push({
|
|
116
|
-
file: filePath,
|
|
117
|
-
line: lineNum + 1,
|
|
118
|
-
column: match.index + 1,
|
|
119
|
-
match: match[0],
|
|
120
|
-
pattern: pattern.source,
|
|
121
|
-
})
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
return violations
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
async function main() {
|
|
130
|
-
const rootDir = process.cwd()
|
|
131
|
-
const allViolations: Violation[] = []
|
|
132
|
-
|
|
133
|
-
console.log('Checking for meta-commentary patterns...\n')
|
|
134
|
-
|
|
135
|
-
for await (const filePath of walkDir(rootDir)) {
|
|
136
|
-
const violations = await checkFile(filePath)
|
|
137
|
-
if (violations.length > 0) {
|
|
138
|
-
allViolations.push(...violations)
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
if (allViolations.length === 0) {
|
|
143
|
-
console.log('✅ No meta-commentary patterns found\n')
|
|
144
|
-
process.exit(0)
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
console.log(`❌ Found ${allViolations.length} meta-commentary violation(s):\n`)
|
|
148
|
-
|
|
149
|
-
// Group by file
|
|
150
|
-
const byFile = new Map<string, Violation[]>()
|
|
151
|
-
for (const v of allViolations) {
|
|
152
|
-
const rel = relative(rootDir, v.file)
|
|
153
|
-
if (!byFile.has(rel)) {
|
|
154
|
-
byFile.set(rel, [])
|
|
155
|
-
}
|
|
156
|
-
byFile.get(rel)!.push(v)
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
for (const [file, violations] of byFile) {
|
|
160
|
-
console.log(` ${file}`)
|
|
161
|
-
for (const v of violations) {
|
|
162
|
-
console.log(` ${v.line}:${v.column} "${v.match}"`)
|
|
163
|
-
}
|
|
164
|
-
console.log('')
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
console.log('Fix: Present preferences as facts, not memories.')
|
|
168
|
-
console.log(' ❌ "I remember you prefer TypeScript"')
|
|
169
|
-
console.log(' ✅ "Use TypeScript"\n')
|
|
170
|
-
|
|
171
|
-
process.exit(1)
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
main().catch((err) => {
|
|
175
|
-
console.error('Error:', err.message)
|
|
176
|
-
process.exit(1)
|
|
177
|
-
})
|