shift-ax 0.3.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.
Files changed (148) hide show
  1. package/LICENSE +21 -0
  2. package/README.ko.md +145 -0
  3. package/README.md +143 -0
  4. package/dist/adapters/claude-code/adapter.js +90 -0
  5. package/dist/adapters/codex/adapter.js +94 -0
  6. package/dist/adapters/contracts.js +7 -0
  7. package/dist/adapters/index.js +12 -0
  8. package/dist/core/context/context-bundle.js +300 -0
  9. package/dist/core/context/discovery.js +82 -0
  10. package/dist/core/context/global-index-authoring.js +199 -0
  11. package/dist/core/context/global-knowledge-updates.js +116 -0
  12. package/dist/core/context/glossary.js +73 -0
  13. package/dist/core/context/guided-onboarding.js +233 -0
  14. package/dist/core/context/index-authoring.js +47 -0
  15. package/dist/core/context/index-resolver.js +78 -0
  16. package/dist/core/context/onboarding.js +186 -0
  17. package/dist/core/diagnostics/doctor.js +154 -0
  18. package/dist/core/finalization/commit-message.js +76 -0
  19. package/dist/core/finalization/commit-workflow.js +131 -0
  20. package/dist/core/memory/consolidation.js +99 -0
  21. package/dist/core/memory/decision-register.js +141 -0
  22. package/dist/core/memory/entity-memory.js +25 -0
  23. package/dist/core/memory/learned-debug.js +52 -0
  24. package/dist/core/memory/summary-checkpoints.js +9 -0
  25. package/dist/core/memory/thread-promotion.js +22 -0
  26. package/dist/core/memory/threads.js +66 -0
  27. package/dist/core/memory/topic-recall.js +52 -0
  28. package/dist/core/observability/context-health.js +15 -0
  29. package/dist/core/observability/context-monitor.js +29 -0
  30. package/dist/core/observability/state-handoff.js +78 -0
  31. package/dist/core/observability/topic-status.js +40 -0
  32. package/dist/core/observability/topics-status.js +26 -0
  33. package/dist/core/observability/verification-debt.js +82 -0
  34. package/dist/core/planning/brainstorm.js +120 -0
  35. package/dist/core/planning/escalation.js +69 -0
  36. package/dist/core/planning/execution-handoff.js +61 -0
  37. package/dist/core/planning/execution-launch.js +156 -0
  38. package/dist/core/planning/execution-orchestrator.js +87 -0
  39. package/dist/core/planning/feedback-reactions.js +75 -0
  40. package/dist/core/planning/lifecycle-events.js +45 -0
  41. package/dist/core/planning/plan-review.js +76 -0
  42. package/dist/core/planning/policy-context-sync.js +154 -0
  43. package/dist/core/planning/request-pipeline.js +386 -0
  44. package/dist/core/planning/workflow-state.js +18 -0
  45. package/dist/core/policies/project-profile.js +28 -0
  46. package/dist/core/policies/team-preferences.js +17 -0
  47. package/dist/core/review/aggregate-reviews.js +129 -0
  48. package/dist/core/review/run-lanes.js +376 -0
  49. package/dist/core/settings/global-context-home.js +28 -0
  50. package/dist/core/settings/project-settings.js +37 -0
  51. package/dist/core/shell/platform-shell.js +144 -0
  52. package/dist/core/topics/bootstrap.js +119 -0
  53. package/dist/core/topics/topic-artifacts.js +36 -0
  54. package/dist/core/topics/worktree-runtime.js +141 -0
  55. package/dist/core/topics/worktree.js +8 -0
  56. package/dist/platform/claude-code/bootstrap.js +66 -0
  57. package/dist/platform/claude-code/execution.js +157 -0
  58. package/dist/platform/claude-code/scaffold/CLAUDE.template.md +40 -0
  59. package/dist/platform/claude-code/scaffold/commands/doctor.template.md +11 -0
  60. package/dist/platform/claude-code/scaffold/commands/export-context.template.md +20 -0
  61. package/dist/platform/claude-code/scaffold/commands/onboard.template.md +43 -0
  62. package/dist/platform/claude-code/scaffold/commands/onboarding.template.md +43 -0
  63. package/dist/platform/claude-code/scaffold/commands/request.template.md +19 -0
  64. package/dist/platform/claude-code/scaffold/commands/resume.template.md +12 -0
  65. package/dist/platform/claude-code/scaffold/commands/review.template.md +10 -0
  66. package/dist/platform/claude-code/scaffold/commands/status.template.md +14 -0
  67. package/dist/platform/claude-code/scaffold/commands/topics.template.md +10 -0
  68. package/dist/platform/claude-code/scaffold/hooks/shift-ax-session-start.template.md +29 -0
  69. package/dist/platform/claude-code/tmux.js +35 -0
  70. package/dist/platform/claude-code/upstream/tmux/imported/detached-session.js +40 -0
  71. package/dist/platform/claude-code/upstream/tmux/imported/session-name.js +19 -0
  72. package/dist/platform/claude-code/upstream/worktree/imported/get-worktree-root.js +39 -0
  73. package/dist/platform/claude-code/upstream/worktree/imported/managed-worktree.js +77 -0
  74. package/dist/platform/claude-code/worktree.js +79 -0
  75. package/dist/platform/codex/bootstrap.js +69 -0
  76. package/dist/platform/codex/execution.js +163 -0
  77. package/dist/platform/codex/scaffold/AGENTS.template.md +40 -0
  78. package/dist/platform/codex/scaffold/prompts/doctor.template.md +11 -0
  79. package/dist/platform/codex/scaffold/prompts/export-context.template.md +20 -0
  80. package/dist/platform/codex/scaffold/prompts/onboard.template.md +43 -0
  81. package/dist/platform/codex/scaffold/prompts/onboarding.template.md +43 -0
  82. package/dist/platform/codex/scaffold/prompts/request.template.md +19 -0
  83. package/dist/platform/codex/scaffold/prompts/resume.template.md +14 -0
  84. package/dist/platform/codex/scaffold/prompts/review.template.md +10 -0
  85. package/dist/platform/codex/scaffold/prompts/shift-ax-bootstrap.template.md +23 -0
  86. package/dist/platform/codex/scaffold/prompts/status.template.md +14 -0
  87. package/dist/platform/codex/scaffold/prompts/topics.template.md +10 -0
  88. package/dist/platform/codex/scaffold/skills/doctor/SKILL.template.md +11 -0
  89. package/dist/platform/codex/scaffold/skills/export-context/SKILL.template.md +20 -0
  90. package/dist/platform/codex/scaffold/skills/onboard/SKILL.template.md +43 -0
  91. package/dist/platform/codex/scaffold/skills/request/SKILL.template.md +19 -0
  92. package/dist/platform/codex/scaffold/skills/resume/SKILL.template.md +14 -0
  93. package/dist/platform/codex/scaffold/skills/review/SKILL.template.md +10 -0
  94. package/dist/platform/codex/scaffold/skills/status/SKILL.template.md +14 -0
  95. package/dist/platform/codex/scaffold/skills/topics/SKILL.template.md +10 -0
  96. package/dist/platform/codex/tmux.js +45 -0
  97. package/dist/platform/codex/upstream/tmux/imported/resize-hook-registration.js +37 -0
  98. package/dist/platform/codex/upstream/tmux/imported/resize-hooks.js +29 -0
  99. package/dist/platform/codex/upstream/tmux/imported/sanitize-team-name.js +18 -0
  100. package/dist/platform/codex/upstream/worktree/imported/managed-worktree.js +208 -0
  101. package/dist/platform/codex/upstream/worktree/imported/resolve-repo-root.js +14 -0
  102. package/dist/platform/codex/worktree.js +99 -0
  103. package/dist/platform/index.js +10 -0
  104. package/dist/platform/product-shell-commands.js +17 -0
  105. package/dist/platform/scaffold.js +16 -0
  106. package/dist/platform/upstream-imports.js +5 -0
  107. package/dist/scripts/ax-approve-plan.js +30 -0
  108. package/dist/scripts/ax-bootstrap-assets.js +19 -0
  109. package/dist/scripts/ax-bootstrap-topic.js +24 -0
  110. package/dist/scripts/ax-build-context-bundle.js +35 -0
  111. package/dist/scripts/ax-checkpoint-context.js +22 -0
  112. package/dist/scripts/ax-consolidate-memory.js +7 -0
  113. package/dist/scripts/ax-context-health.js +26 -0
  114. package/dist/scripts/ax-decisions.js +32 -0
  115. package/dist/scripts/ax-doctor.js +25 -0
  116. package/dist/scripts/ax-entity-memory.js +19 -0
  117. package/dist/scripts/ax-export-context.js +8 -0
  118. package/dist/scripts/ax-finalize-commit.js +23 -0
  119. package/dist/scripts/ax-init-context.js +41 -0
  120. package/dist/scripts/ax-launch-execution.js +24 -0
  121. package/dist/scripts/ax-learned-debug-save.js +30 -0
  122. package/dist/scripts/ax-learned-debug.js +12 -0
  123. package/dist/scripts/ax-monitor-context.js +28 -0
  124. package/dist/scripts/ax-onboard-context.js +112 -0
  125. package/dist/scripts/ax-pause-work.js +33 -0
  126. package/dist/scripts/ax-platform-manifest.js +19 -0
  127. package/dist/scripts/ax-promote-thread.js +20 -0
  128. package/dist/scripts/ax-react-feedback.js +28 -0
  129. package/dist/scripts/ax-recall-topics.js +20 -0
  130. package/dist/scripts/ax-recall.js +58 -0
  131. package/dist/scripts/ax-refresh-state.js +15 -0
  132. package/dist/scripts/ax-resolve-context.js +34 -0
  133. package/dist/scripts/ax-review.js +24 -0
  134. package/dist/scripts/ax-run-request.js +198 -0
  135. package/dist/scripts/ax-scaffold-build.js +19 -0
  136. package/dist/scripts/ax-shell.js +123 -0
  137. package/dist/scripts/ax-sync-policy-context.js +40 -0
  138. package/dist/scripts/ax-team-preferences.js +20 -0
  139. package/dist/scripts/ax-thread-save.js +26 -0
  140. package/dist/scripts/ax-threads.js +11 -0
  141. package/dist/scripts/ax-topic-status.js +18 -0
  142. package/dist/scripts/ax-topics-status.js +22 -0
  143. package/dist/scripts/ax-verification-debt.js +22 -0
  144. package/dist/scripts/ax-worktree-create.js +22 -0
  145. package/dist/scripts/ax-worktree-plan.js +18 -0
  146. package/dist/scripts/ax-worktree-remove.js +18 -0
  147. package/dist/scripts/ax.js +132 -0
  148. package/package.json +71 -0
@@ -0,0 +1,198 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync } from 'node:fs';
3
+ import { createInterface } from 'node:readline/promises';
4
+ import { stderr, stdin } from 'node:process';
5
+ import { getPlatformAdapter } from '../adapters/index.js';
6
+ import { resolveContextFromIndex } from '../core/context/index-resolver.js';
7
+ import { orchestrateExecutionTasks } from '../core/planning/execution-orchestrator.js';
8
+ import { resumeRequestPipeline, startRequestPipeline, } from '../core/planning/request-pipeline.js';
9
+ import { buildPlanningArtifactsFromInterview, } from '../core/planning/brainstorm.js';
10
+ import { parseEscalationArgument } from '../core/planning/escalation.js';
11
+ import { defaultEngineeringDefaults, readProjectProfile, } from '../core/policies/project-profile.js';
12
+ import { getGlobalContextHome } from '../core/settings/global-context-home.js';
13
+ function usage() {
14
+ process.stderr.write([
15
+ 'Usage:',
16
+ ' ax-run-request --request "<text>" [--summary "<text>"] [--brainstorm-file PATH] [--spec-file PATH] [--plan-file PATH] [--index PATH] [--root DIR] [--base BRANCH]',
17
+ ' ax-run-request --topic DIR --resume [--platform <codex|claude-code>] [--verify-command CMD]... [--escalation KIND[:summary]]... [--clear-escalations] [--escalation-resolution "<text>"] [--no-auto-commit]',
18
+ '',
19
+ ].join('\n'));
20
+ }
21
+ function readArg(flag) {
22
+ const index = process.argv.indexOf(flag);
23
+ if (index === -1)
24
+ return undefined;
25
+ return process.argv[index + 1];
26
+ }
27
+ function readArgs(flag) {
28
+ const values = [];
29
+ process.argv.forEach((arg, index) => {
30
+ if (arg === flag && process.argv[index + 1]) {
31
+ values.push(process.argv[index + 1]);
32
+ }
33
+ });
34
+ return values;
35
+ }
36
+ async function readMaybeFile(path) {
37
+ if (!path)
38
+ return undefined;
39
+ const { readFile } = await import('node:fs/promises');
40
+ return readFile(path, 'utf8');
41
+ }
42
+ async function promptInteractivePlanning(request, matchedContextLabels, rootDir) {
43
+ const profile = (await readProjectProfile(rootDir)) ?? {
44
+ engineering_defaults: defaultEngineeringDefaults(),
45
+ };
46
+ const fallbackAnswers = !stdin.isTTY
47
+ ? (await new Promise((resolve, reject) => {
48
+ let raw = '';
49
+ stdin.setEncoding('utf8');
50
+ stdin.on('data', (chunk) => {
51
+ raw += chunk;
52
+ });
53
+ stdin.on('end', () => resolve(raw));
54
+ stdin.on('error', reject);
55
+ }))
56
+ .split(/\r?\n/)
57
+ : null;
58
+ let fallbackIndex = 0;
59
+ const rl = stdin.isTTY
60
+ ? createInterface({
61
+ input: stdin,
62
+ output: stderr,
63
+ })
64
+ : null;
65
+ const ask = async (question) => {
66
+ if (rl) {
67
+ return rl.question(question);
68
+ }
69
+ stderr.write(question);
70
+ const answer = fallbackAnswers?.[fallbackIndex] ?? '';
71
+ fallbackIndex += 1;
72
+ return answer;
73
+ };
74
+ const answers = {
75
+ outcome: (await ask('Clarified outcome: ')).trim(),
76
+ constraints: (await ask('Constraints or policy notes: ')).trim(),
77
+ outOfScope: (await ask('Explicitly out of scope: ')).trim(),
78
+ verification: (await ask('Verification / tests that should prove this: ')).trim(),
79
+ implementationAreas: (await ask('Likely implementation areas: ')).trim(),
80
+ longRunningWork: (await ask('Any long-running or cross-cutting work: ')).trim(),
81
+ policyUpdates: (await ask('Global knowledge updates to add or refine before implementation: ')).trim(),
82
+ };
83
+ rl?.close();
84
+ return buildPlanningArtifactsFromInterview({
85
+ request,
86
+ matchedContextLabels,
87
+ answers,
88
+ engineeringDefaults: profile.engineering_defaults,
89
+ });
90
+ }
91
+ async function resolveMatchedContextLabels(rootDir, query, indexPath) {
92
+ const home = getGlobalContextHome();
93
+ const effectiveIndexPath = indexPath || (existsSync(home.indexPath) ? home.indexPath : `${rootDir}/docs/base-context/index.md`);
94
+ if (!existsSync(effectiveIndexPath)) {
95
+ return [];
96
+ }
97
+ const resolved = await resolveContextFromIndex({
98
+ rootDir,
99
+ indexPath: effectiveIndexPath,
100
+ indexRootDir: effectiveIndexPath === home.indexPath ? home.root : rootDir,
101
+ query,
102
+ });
103
+ return resolved.matches.map((match) => match.label);
104
+ }
105
+ function buildContextResolutionQuery({ request, brainstormContent, specContent, implementationPlanContent, }) {
106
+ return [
107
+ request.trim(),
108
+ brainstormContent?.trim() ?? '',
109
+ specContent?.trim() ?? '',
110
+ implementationPlanContent?.trim() ?? '',
111
+ ]
112
+ .filter(Boolean)
113
+ .join('\n\n');
114
+ }
115
+ async function main() {
116
+ const topicDir = readArg('--topic');
117
+ const resume = process.argv.includes('--resume');
118
+ const platform = readArg('--platform');
119
+ if (resume) {
120
+ if (!topicDir) {
121
+ usage();
122
+ process.exit(1);
123
+ }
124
+ if (platform && platform !== 'codex' && platform !== 'claude-code') {
125
+ usage();
126
+ process.exit(1);
127
+ }
128
+ const runtimePlatform = platform === 'codex' || platform === 'claude-code' ? platform : undefined;
129
+ const executionRunner = runtimePlatform
130
+ ? async ({ topicDir }) => {
131
+ const adapter = getPlatformAdapter(runtimePlatform);
132
+ const plan = await adapter.planExecution({ topicDir });
133
+ return orchestrateExecutionTasks({
134
+ topicDir,
135
+ tasks: plan.tasks,
136
+ runTask: async (task) => {
137
+ await adapter.launchExecution({
138
+ topicDir,
139
+ taskId: task.task_id,
140
+ });
141
+ },
142
+ });
143
+ }
144
+ : undefined;
145
+ const result = await resumeRequestPipeline({
146
+ topicDir,
147
+ verificationCommands: readArgs('--verify-command'),
148
+ escalationTriggers: readArgs('--escalation').map((value) => parseEscalationArgument(value)),
149
+ clearEscalations: process.argv.includes('--clear-escalations'),
150
+ escalationResolution: readArg('--escalation-resolution'),
151
+ autoCommit: !process.argv.includes('--no-auto-commit'),
152
+ executionRunner,
153
+ });
154
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
155
+ return;
156
+ }
157
+ const request = readArg('--request');
158
+ if (!request) {
159
+ usage();
160
+ process.exit(1);
161
+ }
162
+ const rootDir = readArg('--root') || process.cwd();
163
+ const indexPath = readArg('--index');
164
+ const allowMissingGlobalIndex = process.argv.includes('--allow-missing-global-context');
165
+ let brainstormContent = await readMaybeFile(readArg('--brainstorm-file'));
166
+ let specContent = await readMaybeFile(readArg('--spec-file'));
167
+ let implementationPlanContent = await readMaybeFile(readArg('--plan-file'));
168
+ if (!brainstormContent && !specContent && !implementationPlanContent) {
169
+ const matchedContextLabels = await resolveMatchedContextLabels(rootDir, request, indexPath);
170
+ const generated = await promptInteractivePlanning(request, matchedContextLabels, rootDir);
171
+ brainstormContent = generated.brainstormContent;
172
+ specContent = generated.specContent;
173
+ implementationPlanContent = generated.implementationPlanContent;
174
+ }
175
+ const contextQuery = buildContextResolutionQuery({
176
+ request,
177
+ brainstormContent,
178
+ specContent,
179
+ implementationPlanContent,
180
+ });
181
+ const result = await startRequestPipeline({
182
+ rootDir,
183
+ request,
184
+ summary: readArg('--summary'),
185
+ indexPath,
186
+ contextQuery,
187
+ brainstormContent,
188
+ specContent,
189
+ implementationPlanContent,
190
+ baseBranch: readArg('--base') || 'main',
191
+ allowMissingGlobalIndex,
192
+ });
193
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
194
+ }
195
+ void main().catch((error) => {
196
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
197
+ process.exit(1);
198
+ });
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env node
2
+ import { scaffoldPlatformBuild } from '../platform/scaffold.js';
3
+ function usage() {
4
+ process.stderr.write('Usage: ax-scaffold-build --platform <codex|claude-code> [--root DIR]\n');
5
+ }
6
+ function readArg(flag) {
7
+ const index = process.argv.indexOf(flag);
8
+ if (index === -1)
9
+ return undefined;
10
+ return process.argv[index + 1];
11
+ }
12
+ const platform = readArg('--platform');
13
+ const rootDir = readArg('--root') || process.cwd();
14
+ if (platform !== 'codex' && platform !== 'claude-code') {
15
+ usage();
16
+ process.exit(1);
17
+ }
18
+ const result = await scaffoldPlatformBuild({ platform, rootDir });
19
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
@@ -0,0 +1,123 @@
1
+ #!/usr/bin/env node
2
+ import { readFile } from 'node:fs/promises';
3
+ import { isProjectOnboarded, launchPlatformShell, resolveShellDefaultFullAuto, resolveShellLocale, persistShellSettings, } from '../core/shell/platform-shell.js';
4
+ import { onboardProjectContext, onboardProjectContextFromDiscovery } from '../core/context/onboarding.js';
5
+ import { readProjectSettings } from '../core/settings/project-settings.js';
6
+ function readArg(flag) {
7
+ const index = process.argv.indexOf(flag);
8
+ if (index === -1)
9
+ return undefined;
10
+ return process.argv[index + 1];
11
+ }
12
+ function usage() {
13
+ process.stderr.write([
14
+ 'Usage:',
15
+ ' shift-ax --codex [--root DIR] [--lang en|ko] [--full-auto] [--discover] [--overwrite] [--onboarding-input FILE] [initial prompt]',
16
+ ' shift-ax --claude-code [--root DIR] [--lang en|ko] [--full-auto] [--discover] [--overwrite] [--onboarding-input FILE] [initial prompt]',
17
+ ' shift-ax # default product shell launcher (Codex unless global settings say otherwise)',
18
+ '',
19
+ ].join('\n'));
20
+ }
21
+ function parsePlatform() {
22
+ if (process.argv.includes('--codex'))
23
+ return 'codex';
24
+ if (process.argv.includes('--claude-code'))
25
+ return 'claude-code';
26
+ return undefined;
27
+ }
28
+ function parseLocale() {
29
+ const locale = readArg('--lang');
30
+ return locale === 'en' || locale === 'ko' ? locale : undefined;
31
+ }
32
+ function collectPromptArgs() {
33
+ const ignored = new Set([
34
+ '--codex',
35
+ '--claude-code',
36
+ '--full-auto',
37
+ '--discover',
38
+ '--overwrite',
39
+ '--lang',
40
+ '--root',
41
+ '--onboarding-input',
42
+ ]);
43
+ const values = process.argv.slice(2);
44
+ const result = [];
45
+ for (let index = 0; index < values.length; index += 1) {
46
+ const token = values[index];
47
+ if (ignored.has(token)) {
48
+ if (token === '--lang' || token === '--root' || token === '--onboarding-input') {
49
+ index += 1;
50
+ }
51
+ continue;
52
+ }
53
+ result.push(token);
54
+ }
55
+ return result.join(' ').trim();
56
+ }
57
+ const rootDir = readArg('--root') || process.cwd();
58
+ const requestedPlatform = parsePlatform();
59
+ const requestedLocale = parseLocale();
60
+ const onboardingInput = readArg('--onboarding-input');
61
+ const discover = process.argv.includes('--discover');
62
+ const overwrite = process.argv.includes('--overwrite');
63
+ const requestedFullAuto = process.argv.includes('--full-auto');
64
+ const prompt = collectPromptArgs();
65
+ const existingSettings = await readProjectSettings(rootDir);
66
+ const onboarded = await isProjectOnboarded(rootDir);
67
+ if ((requestedLocale === undefined && process.argv.includes('--lang')) || process.argv.includes('--help')) {
68
+ usage();
69
+ process.exit(process.argv.includes('--help') ? 0 : 1);
70
+ }
71
+ const locale = await resolveShellLocale({
72
+ rootDir,
73
+ requestedLocale,
74
+ });
75
+ const platform = requestedPlatform ??
76
+ existingSettings?.preferred_platform ??
77
+ 'codex';
78
+ const defaultFullAuto = await resolveShellDefaultFullAuto({
79
+ rootDir,
80
+ locale,
81
+ });
82
+ const effectiveFullAuto = defaultFullAuto || requestedFullAuto;
83
+ if (!onboarded) {
84
+ if (onboardingInput) {
85
+ await onboardProjectContext({
86
+ ...JSON.parse(await readFile(onboardingInput, 'utf8')),
87
+ rootDir,
88
+ overwrite,
89
+ });
90
+ await persistShellSettings({
91
+ rootDir,
92
+ locale,
93
+ defaultFullAuto,
94
+ platform,
95
+ });
96
+ }
97
+ else if (discover) {
98
+ await onboardProjectContextFromDiscovery({
99
+ rootDir,
100
+ includeGlossary: true,
101
+ overwrite,
102
+ });
103
+ await persistShellSettings({
104
+ rootDir,
105
+ locale,
106
+ defaultFullAuto,
107
+ platform,
108
+ });
109
+ }
110
+ }
111
+ await persistShellSettings({
112
+ rootDir,
113
+ locale,
114
+ defaultFullAuto,
115
+ platform,
116
+ });
117
+ const exitCode = await launchPlatformShell({
118
+ rootDir,
119
+ platform,
120
+ fullAuto: effectiveFullAuto,
121
+ ...(prompt ? { initialPrompt: prompt } : {}),
122
+ });
123
+ process.exit(exitCode);
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env node
2
+ import { completePolicyContextSync } from '../core/planning/policy-context-sync.js';
3
+ function usage() {
4
+ process.stderr.write('Usage: ax-sync-policy-context --topic DIR --summary "<text>" [--path REL_PATH]... [--entry "Label -> path"]...\n');
5
+ }
6
+ function readArg(flag) {
7
+ const index = process.argv.indexOf(flag);
8
+ if (index === -1)
9
+ return undefined;
10
+ return process.argv[index + 1];
11
+ }
12
+ function readArgs(flag) {
13
+ const values = [];
14
+ process.argv.forEach((arg, index) => {
15
+ if (arg === flag && process.argv[index + 1]) {
16
+ values.push(process.argv[index + 1]);
17
+ }
18
+ });
19
+ return values;
20
+ }
21
+ function parseEntry(value) {
22
+ const [label, path] = value.split('->').map((part) => part.trim());
23
+ if (!label || !path) {
24
+ throw new Error(`invalid --entry value: ${value}`);
25
+ }
26
+ return { label, path };
27
+ }
28
+ const topicDir = readArg('--topic');
29
+ const summary = readArg('--summary');
30
+ if (!topicDir || !summary) {
31
+ usage();
32
+ process.exit(1);
33
+ }
34
+ const result = await completePolicyContextSync({
35
+ topicDir,
36
+ summary,
37
+ syncedPaths: readArgs('--path'),
38
+ syncedEntries: readArgs('--entry').map(parseEntry),
39
+ });
40
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env node
2
+ import { readFile } from 'node:fs/promises';
3
+ import { readTeamPreferences, writeTeamPreferences } from '../core/policies/team-preferences.js';
4
+ function readArg(flag) {
5
+ const index = process.argv.indexOf(flag);
6
+ if (index === -1)
7
+ return undefined;
8
+ return process.argv[index + 1];
9
+ }
10
+ const rootDir = readArg('--root') || process.cwd();
11
+ const inputPath = readArg('--input');
12
+ if (inputPath) {
13
+ const raw = await readFile(inputPath, 'utf8');
14
+ await writeTeamPreferences({
15
+ rootDir,
16
+ preferences: JSON.parse(raw),
17
+ });
18
+ }
19
+ const result = await readTeamPreferences(rootDir);
20
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env node
2
+ import { saveThreadNote } from '../core/memory/threads.js';
3
+ function usage() {
4
+ process.stderr.write('Usage: ax-thread-save --root DIR --name NAME [--summary "<text>"] --note "<text>"\n');
5
+ }
6
+ function readArg(flag) {
7
+ const index = process.argv.indexOf(flag);
8
+ if (index === -1)
9
+ return undefined;
10
+ return process.argv[index + 1];
11
+ }
12
+ const rootDir = readArg('--root') || process.cwd();
13
+ const name = readArg('--name');
14
+ const summary = readArg('--summary');
15
+ const note = readArg('--note');
16
+ if (!name || !note) {
17
+ usage();
18
+ process.exit(1);
19
+ }
20
+ const result = await saveThreadNote({
21
+ rootDir,
22
+ name,
23
+ ...(summary ? { summary } : {}),
24
+ note,
25
+ });
26
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ import { listThreads } from '../core/memory/threads.js';
3
+ function readArg(flag) {
4
+ const index = process.argv.indexOf(flag);
5
+ if (index === -1)
6
+ return undefined;
7
+ return process.argv[index + 1];
8
+ }
9
+ const rootDir = readArg('--root') || process.cwd();
10
+ const result = await listThreads({ rootDir });
11
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ import { summarizeTopicStatus } from '../core/observability/topic-status.js';
3
+ function usage() {
4
+ process.stderr.write('Usage: ax-topic-status --topic DIR\n');
5
+ }
6
+ function readArg(flag) {
7
+ const index = process.argv.indexOf(flag);
8
+ if (index === -1)
9
+ return undefined;
10
+ return process.argv[index + 1];
11
+ }
12
+ const topicDir = readArg('--topic');
13
+ if (!topicDir) {
14
+ usage();
15
+ process.exit(1);
16
+ }
17
+ const summary = await summarizeTopicStatus(topicDir);
18
+ process.stdout.write(`${JSON.stringify(summary, null, 2)}\n`);
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env node
2
+ import { listTopicsStatus } from '../core/observability/topics-status.js';
3
+ function usage() {
4
+ process.stderr.write('Usage: ax-topics-status [--root DIR] [--limit N]\n');
5
+ }
6
+ function readArg(flag) {
7
+ const index = process.argv.indexOf(flag);
8
+ if (index === -1)
9
+ return undefined;
10
+ return process.argv[index + 1];
11
+ }
12
+ const rootDir = readArg('--root') || process.cwd();
13
+ const limit = Number(readArg('--limit') || '10');
14
+ if (process.argv.includes('--help')) {
15
+ usage();
16
+ process.exit(0);
17
+ }
18
+ const result = await listTopicsStatus({
19
+ rootDir,
20
+ limit: Number.isFinite(limit) && limit > 0 ? limit : 10,
21
+ });
22
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env node
2
+ import { listVerificationDebt } from '../core/observability/verification-debt.js';
3
+ function usage() {
4
+ process.stderr.write('Usage: ax-verification-debt [--root DIR] [--topic DIR]\n');
5
+ }
6
+ function readArg(flag) {
7
+ const index = process.argv.indexOf(flag);
8
+ if (index === -1)
9
+ return undefined;
10
+ return process.argv[index + 1];
11
+ }
12
+ const rootDir = readArg('--root');
13
+ const topicDir = readArg('--topic');
14
+ if (!rootDir && !topicDir) {
15
+ usage();
16
+ process.exit(1);
17
+ }
18
+ const result = await listVerificationDebt({
19
+ ...(rootDir ? { rootDir } : {}),
20
+ ...(topicDir ? { topicDir } : {}),
21
+ });
22
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env node
2
+ import { createTopicWorktree } from '../core/topics/worktree-runtime.js';
3
+ function usage() {
4
+ process.stderr.write('Usage: ax-worktree-create --topic DIR [--base BRANCH]\n');
5
+ }
6
+ function readArg(flag) {
7
+ const index = process.argv.indexOf(flag);
8
+ if (index === -1)
9
+ return undefined;
10
+ return process.argv[index + 1];
11
+ }
12
+ const topicDir = readArg('--topic');
13
+ const baseBranch = readArg('--base') || 'main';
14
+ if (!topicDir) {
15
+ usage();
16
+ process.exit(1);
17
+ }
18
+ const result = await createTopicWorktree({
19
+ topicDir,
20
+ baseBranch,
21
+ });
22
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ import { planTopicWorktree } from '../core/topics/worktree-runtime.js';
3
+ function usage() {
4
+ process.stderr.write('Usage: ax-worktree-plan --topic DIR\n');
5
+ }
6
+ function readArg(flag) {
7
+ const index = process.argv.indexOf(flag);
8
+ if (index === -1)
9
+ return undefined;
10
+ return process.argv[index + 1];
11
+ }
12
+ const topicDir = readArg('--topic');
13
+ if (!topicDir) {
14
+ usage();
15
+ process.exit(1);
16
+ }
17
+ const plan = await planTopicWorktree({ topicDir });
18
+ process.stdout.write(`${JSON.stringify(plan, null, 2)}\n`);
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ import { removeTopicWorktree } from '../core/topics/worktree-runtime.js';
3
+ function usage() {
4
+ process.stderr.write('Usage: ax-worktree-remove --topic DIR\n');
5
+ }
6
+ function readArg(flag) {
7
+ const index = process.argv.indexOf(flag);
8
+ if (index === -1)
9
+ return undefined;
10
+ return process.argv[index + 1];
11
+ }
12
+ const topicDir = readArg('--topic');
13
+ if (!topicDir) {
14
+ usage();
15
+ process.exit(1);
16
+ }
17
+ const result = await removeTopicWorktree({ topicDir });
18
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);