@aopslabs/aops 0.3.30 → 0.3.32

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 (147) hide show
  1. package/README.md +11 -3
  2. package/aops-assets-release/aops-assets.json.gz +0 -0
  3. package/aops-assets-release/disciplines/build-review-chat/SKILL.md +33 -0
  4. package/aops-assets-release/disciplines/coordinator-loop/SKILL.md +33 -0
  5. package/aops-assets-release/disciplines/design-first-consensus/SKILL.md +30 -0
  6. package/aops-assets-release/disciplines/solo-pm-loop/SKILL.md +31 -0
  7. package/aops-assets-release/docs/user-guides/agentspace-user-guide.md +384 -0
  8. package/aops-assets-release/docs/user-guides/aops-cli-user-guide.md +2067 -0
  9. package/aops-assets-release/docs/user-guides/chatv3-user-guide.md +500 -0
  10. package/aops-assets-release/docs/user-guides/docman-user-guide.md +1009 -0
  11. package/aops-assets-release/docs/user-guides/projectman-user-guide.md +763 -0
  12. package/aops-assets-release/docs/user-guides/tasker-user-guide.md +244 -0
  13. package/aops-assets-release/release.json +6 -0
  14. package/aops-assets-release/roles/coordinator/ROLE.md +28 -0
  15. package/aops-assets-release/roles/implementer/ROLE.md +27 -0
  16. package/aops-assets-release/roles/reviewer/ROLE.md +27 -0
  17. package/aops-assets-release/skills/aops/SKILL.md +112 -0
  18. package/aops-assets-release/skills/aops-bootstrapper-authoring/SKILL.md +245 -0
  19. package/aops-assets-release/skills/aops-cli-agentspace/SKILL.md +186 -0
  20. package/aops-assets-release/skills/aops-cli-board-lifecycle/SKILL.md +64 -0
  21. package/aops-assets-release/skills/aops-cli-chat/SKILL.md +204 -0
  22. package/aops-assets-release/skills/aops-cli-collab/SKILL.md +42 -0
  23. package/aops-assets-release/skills/aops-cli-core/SKILL.md +219 -0
  24. package/aops-assets-release/skills/aops-cli-discuss/SKILL.md +172 -0
  25. package/aops-assets-release/skills/aops-cli-docman/SKILL.md +192 -0
  26. package/aops-assets-release/skills/aops-cli-fileman/SKILL.md +169 -0
  27. package/aops-assets-release/skills/aops-cli-mission/SKILL.md +128 -0
  28. package/aops-assets-release/skills/aops-cli-operator-brief/SKILL.md +67 -0
  29. package/aops-assets-release/skills/aops-cli-projectman/SKILL.md +235 -0
  30. package/aops-assets-release/skills/aops-cli-sugar-authoring/SKILL.md +188 -0
  31. package/aops-assets-release/skills/aops-cli-tasker/SKILL.md +108 -0
  32. package/aops-assets-release/skills/aops-cli-tooling-agent/SKILL.md +112 -0
  33. package/aops-assets-release/skills/aops-cli-view/SKILL.md +210 -0
  34. package/aops-assets-release/skills/aops-collaborative-work/SKILL.md +304 -0
  35. package/aops-assets-release/skills/aops-interactive/SKILL.md +70 -0
  36. package/aops-assets-release/skills/aops-loop-interactive/SKILL.md +314 -0
  37. package/aops-assets-release/skills/aops-working-disciplines/SKILL.md +310 -0
  38. package/aops-assets-release/skills/feature-retirement-flow/SKILL.md +126 -0
  39. package/assets/skills/aops-install/SKILL.md +18 -17
  40. package/dist/commands/assets.js +93 -1264
  41. package/dist/commands/community-server.js +27 -8
  42. package/dist/commands/community-setup.js +1 -2
  43. package/dist/commands/discuss.js +1 -1
  44. package/dist/commands/doc.js +88 -27
  45. package/dist/commands/docs.js +68 -0
  46. package/dist/commands/global-update.js +28 -0
  47. package/dist/commands/init.js +3 -1
  48. package/dist/commands/loop.js +6379 -0
  49. package/dist/commands/memory.js +2 -1
  50. package/dist/commands/pm/index.js +11 -9
  51. package/dist/commands/pm/projectman.js +33 -2
  52. package/dist/commands/project.js +6 -6
  53. package/dist/commands/prompt.js +1 -1
  54. package/dist/commands/repo-sync.js +92 -27
  55. package/dist/commands/runner.js +257 -0
  56. package/dist/commands/skill.js +1 -1
  57. package/dist/commands/start.js +1 -1
  58. package/dist/commands/tasker.js +361 -0
  59. package/dist/commands/view.js +53 -9
  60. package/dist/lib/commercial-setup-readiness-adapter.js +0 -1
  61. package/dist/lib/community-migration-snapshot.js +7 -9
  62. package/dist/lib/community-native-database-recovery.js +5 -14
  63. package/dist/lib/community-native-lifecycle.js +13 -0
  64. package/dist/lib/setup-agent-assets-bridge.js +28 -148
  65. package/dist/lib/setup-agent-assets-release.js +16 -44
  66. package/dist/lib/setup-init-orchestrator.js +11 -15
  67. package/dist/lib/simple-agent-assets.js +447 -0
  68. package/dist/lib/user-guide-sections.js +488 -0
  69. package/dist/main.js +10 -2
  70. package/dist/seeds/agents-md.js +3 -3
  71. package/dist/utils/agents-md.js +1 -1
  72. package/dist/utils/guide-paths.js +7 -7
  73. package/dist/utils/hosted-workspace.js +2 -1
  74. package/dist/utils/repo-first-storage.js +26 -1
  75. package/dist/utils/session-state.js +2 -7
  76. package/launchers/aops-cockpit.sh +0 -0
  77. package/launchers/aops-server.sh +0 -0
  78. package/package.json +67 -35
  79. package/THIRD_PARTY_NOTICES +0 -16169
  80. package/agent-assets-release/agent-assets/core/bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb/files/SKILL.md +0 -47
  81. package/agent-assets-release/agent-assets/core/bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb/files/references/agentspace/SKILL.md +0 -72
  82. package/agent-assets-release/agent-assets/core/bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb/files/references/aops-cli-core/SKILL.md +0 -110
  83. package/agent-assets-release/agent-assets/core/bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb/files/references/chatv3/SKILL.md +0 -59
  84. package/agent-assets-release/agent-assets/core/bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb/files/references/collaborative-work/SKILL.md +0 -81
  85. package/agent-assets-release/agent-assets/core/bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb/files/references/discuss/SKILL.md +0 -66
  86. package/agent-assets-release/agent-assets/core/bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb/files/references/docman/SKILL.md +0 -75
  87. package/agent-assets-release/agent-assets/core/bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb/files/references/projectman/SKILL.md +0 -92
  88. package/agent-assets-release/agent-assets/core/bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb/files/references/sys/SKILL.md +0 -36
  89. package/agent-assets-release/agent-assets/core/bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb/files/references/view/SKILL.md +0 -58
  90. package/agent-assets-release/agent-assets/core/bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb/files/references/working-disciplines/SKILL.md +0 -66
  91. package/agent-assets-release/agent-assets/core/bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb/files/user-guides/agent-assets.md +0 -81
  92. package/agent-assets-release/agent-assets/core/bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb/files/user-guides/agentspace.md +0 -183
  93. package/agent-assets-release/agent-assets/core/bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb/files/user-guides/aops-cli.md +0 -1108
  94. package/agent-assets-release/agent-assets/core/bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb/files/user-guides/aops-system.md +0 -102
  95. package/agent-assets-release/agent-assets/core/bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb/files/user-guides/chatv3.md +0 -113
  96. package/agent-assets-release/agent-assets/core/bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb/files/user-guides/docman.md +0 -223
  97. package/agent-assets-release/agent-assets/core/bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb/files/user-guides/projectman.md +0 -233
  98. package/agent-assets-release/agent-assets/core/bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb/files/user-guides/sys.md +0 -94
  99. package/agent-assets-release/agent-assets/core/bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb/files/user-guides/working-disciplines.md +0 -482
  100. package/agent-assets-release/agent-assets/core/bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb/manifest.json +0 -117
  101. package/agent-assets-release/agent-assets/gateway/aops/SKILL.md +0 -14
  102. package/agent-assets-release/agent-assets/inventory.json +0 -29
  103. package/agent-assets-release/agent-assets/projection.json +0 -8
  104. package/agent-assets-release/agent-assets-release.json +0 -171
  105. package/agent-assets-release/agent-assets-release.sigstore.json +0 -67
  106. package/assets/agent-assets/core/SKILL.md +0 -47
  107. package/assets/agent-assets/core/references/agentspace/SKILL.md +0 -72
  108. package/assets/agent-assets/core/references/aops-cli-core/SKILL.md +0 -110
  109. package/assets/agent-assets/core/references/chatv3/SKILL.md +0 -59
  110. package/assets/agent-assets/core/references/collaborative-work/SKILL.md +0 -81
  111. package/assets/agent-assets/core/references/discuss/SKILL.md +0 -66
  112. package/assets/agent-assets/core/references/docman/SKILL.md +0 -75
  113. package/assets/agent-assets/core/references/projectman/SKILL.md +0 -92
  114. package/assets/agent-assets/core/references/sys/SKILL.md +0 -36
  115. package/assets/agent-assets/core/references/view/SKILL.md +0 -58
  116. package/assets/agent-assets/core/references/working-disciplines/SKILL.md +0 -66
  117. package/assets/agent-assets/core/user-guides/agent-assets.md +0 -81
  118. package/assets/agent-assets/core/user-guides/agentspace.md +0 -183
  119. package/assets/agent-assets/core/user-guides/aops-cli.md +0 -1108
  120. package/assets/agent-assets/core/user-guides/aops-system.md +0 -102
  121. package/assets/agent-assets/core/user-guides/chatv3.md +0 -113
  122. package/assets/agent-assets/core/user-guides/docman.md +0 -223
  123. package/assets/agent-assets/core/user-guides/projectman.md +0 -233
  124. package/assets/agent-assets/core/user-guides/sys.md +0 -94
  125. package/assets/agent-assets/core/user-guides/working-disciplines.md +0 -482
  126. package/assets/agent-assets/gateway/aops/SKILL.md +0 -14
  127. package/dist/lib/agent-assets/gateway.js +0 -15
  128. package/dist/lib/agent-assets/guards.js +0 -23
  129. package/dist/lib/agent-assets/hosted-discovery.js +0 -148
  130. package/dist/lib/agent-assets/hosted-package-input.js +0 -154
  131. package/dist/lib/agent-assets/legacy-pointer-migration.js +0 -677
  132. package/dist/lib/agent-assets/native-fs.js +0 -589
  133. package/dist/lib/agent-assets/roots.js +0 -45
  134. package/dist/lib/agent-assets/runtime-binding-reader.js +0 -545
  135. package/dist/lib/agent-assets/runtime-targets.js +0 -50
  136. package/dist/lib/agent-assets/store-reader.js +0 -1212
  137. package/dist/lib/agent-assets/store-writer.js +0 -1484
  138. package/native/bin/darwin-arm64/aops-agent-assets-fs +0 -0
  139. package/native/bin/darwin-x64/aops-agent-assets-fs +0 -0
  140. package/native/bin/linux-arm64/aops-agent-assets-fs +0 -0
  141. package/native/bin/linux-x64/aops-agent-assets-fs +0 -0
  142. package/native/bin/win32-x64/aops-agent-assets-fs.exe +0 -0
  143. package/native/manifest.json +0 -49
  144. package/native/qualifications/win32-x64.json +0 -23
  145. package/native/tui/darwin-arm64/aops-tui +0 -0
  146. package/native/tui/linux-x64/aops-tui +0 -0
  147. package/native/tui/win32-x64/aops-tui.exe +0 -0
@@ -0,0 +1,488 @@
1
+ export const COMMAND_CATALOG_START = '<!-- aops-generated:cli-command-catalog:start -->';
2
+ export const COMMAND_CATALOG_END = '<!-- aops-generated:cli-command-catalog:end -->';
3
+ export const DISCOVERY_GUIDE_START = '<!-- aops-generated:capability-discovery:start -->';
4
+ export const DISCOVERY_GUIDE_END = '<!-- aops-generated:capability-discovery:end -->';
5
+ export const DOCMAN_COMMAND_CATALOG_START = '<!-- aops-generated:docman-command-catalog:start -->';
6
+ export const DOCMAN_COMMAND_CATALOG_END = '<!-- aops-generated:docman-command-catalog:end -->';
7
+ export const DOCMAN_DISCOVERY_GUIDE_START = '<!-- aops-generated:docman-discovery:start -->';
8
+ export const DOCMAN_DISCOVERY_GUIDE_END = '<!-- aops-generated:docman-discovery:end -->';
9
+ export const CHATV3_COMMAND_CATALOG_START = '<!-- aops-generated:chatv3-command-catalog:start -->';
10
+ export const CHATV3_COMMAND_CATALOG_END = '<!-- aops-generated:chatv3-command-catalog:end -->';
11
+ export const CHATV3_DISCOVERY_GUIDE_START = '<!-- aops-generated:chatv3-discovery:start -->';
12
+ export const CHATV3_DISCOVERY_GUIDE_END = '<!-- aops-generated:chatv3-discovery:end -->';
13
+ export const AGENTSPACE_COMMAND_CATALOG_START = '<!-- aops-generated:agentspace-command-catalog:start -->';
14
+ export const AGENTSPACE_COMMAND_CATALOG_END = '<!-- aops-generated:agentspace-command-catalog:end -->';
15
+ export const AGENTSPACE_DISCOVERY_GUIDE_START = '<!-- aops-generated:agentspace-discovery:start -->';
16
+ export const AGENTSPACE_DISCOVERY_GUIDE_END = '<!-- aops-generated:agentspace-discovery:end -->';
17
+ export const TASKER_COMMAND_CATALOG_START = '<!-- aops-generated:tasker-command-catalog:start -->';
18
+ export const TASKER_COMMAND_CATALOG_END = '<!-- aops-generated:tasker-command-catalog:end -->';
19
+ export const TASKER_DISCOVERY_GUIDE_START = '<!-- aops-generated:tasker-discovery:start -->';
20
+ export const TASKER_DISCOVERY_GUIDE_END = '<!-- aops-generated:tasker-discovery:end -->';
21
+ export const APPENDICES_HEADING = '## Appendices';
22
+ const COMPATIBILITY_COMMAND_TREES = new Map([
23
+ ['chatv3', 'chat'],
24
+ ]);
25
+ const AGENTSPACE_COMMAND_FAMILIES = [
26
+ 'mem',
27
+ 'exp',
28
+ 'project',
29
+ 'playbook',
30
+ 'prompt',
31
+ 'resource',
32
+ 'artifact',
33
+ 'skill',
34
+ 'agent-profile',
35
+ 'activity',
36
+ 'discuss',
37
+ ];
38
+ function oneLine(value) {
39
+ return value.replace(/\s+/gu, ' ').trim();
40
+ }
41
+ function tableCell(value) {
42
+ return oneLine(value).replace(/\|/gu, '\\|');
43
+ }
44
+ function isHidden(command) {
45
+ return command._hidden === true;
46
+ }
47
+ function collectCommands(root) {
48
+ const rootName = root.name();
49
+ const descriptors = [];
50
+ const visit = (parentPath, command) => {
51
+ if (isHidden(command))
52
+ return;
53
+ const segments = [...parentPath, command.name()];
54
+ const commandPath = [rootName, ...segments].join(' ');
55
+ descriptors.push({
56
+ path: commandPath,
57
+ description: oneLine(command.description()),
58
+ aliases: command.aliases().map(oneLine).filter(Boolean).sort(),
59
+ depth: segments.length,
60
+ family: segments[0] ?? command.name(),
61
+ leaf: command.commands.length === 0,
62
+ compatibilityOf: COMPATIBILITY_COMMAND_TREES.get(segments[0] ?? ''),
63
+ });
64
+ for (const child of [...command.commands].sort((left, right) => left.name().localeCompare(right.name()))) {
65
+ visit(segments, child);
66
+ }
67
+ };
68
+ for (const command of [...root.commands].sort((left, right) => left.name().localeCompare(right.name()))) {
69
+ visit([], command);
70
+ }
71
+ return descriptors.sort((left, right) => left.path.localeCompare(right.path));
72
+ }
73
+ function commandLabel(command) {
74
+ const aliases = command.aliases.length > 0 ? ` (aliases: ${command.aliases.join(', ')})` : '';
75
+ return `\`${command.path}\`${aliases}`;
76
+ }
77
+ function commandPurpose(command) {
78
+ const description = command.description || `Run \`${command.path} --help\` for the current command contract.`;
79
+ if (command.depth === 1 && command.compatibilityOf) {
80
+ return `Compatibility command tree for canonical \`aops ${command.compatibilityOf}\`. ${description}`;
81
+ }
82
+ return description;
83
+ }
84
+ export function renderCommandCatalog(root) {
85
+ const commands = collectCommands(root);
86
+ const families = commands.filter((command) => command.depth === 1);
87
+ const nestedByFamily = new Map();
88
+ for (const command of commands.filter((entry) => entry.depth > 1)) {
89
+ const familyCommands = nestedByFamily.get(command.family) ?? [];
90
+ familyCommands.push(command);
91
+ nestedByFamily.set(command.family, familyCommands);
92
+ }
93
+ const lines = [
94
+ COMMAND_CATALOG_START,
95
+ '### Generated CLI command catalog',
96
+ '',
97
+ '> This section is generated from the public Commander program registered by `buildCommunityProgram()`. Do not edit it by hand; regenerate it with `aops docs user-guide`.',
98
+ '',
99
+ '#### Command families',
100
+ '',
101
+ '| Command | Purpose |',
102
+ '| --- | --- |',
103
+ ...families.map((command) => `| ${commandLabel(command)} | ${tableCell(commandPurpose(command))} |`),
104
+ ];
105
+ for (const family of families) {
106
+ const nested = nestedByFamily.get(family.family) ?? [];
107
+ if (nested.length === 0)
108
+ continue;
109
+ lines.push('', `#### \`${root.name()} ${family.family}\` commands`, '');
110
+ if (family.compatibilityOf) {
111
+ lines.push(`> Compatibility command tree for canonical \`${root.name()} ${family.compatibilityOf}\`. It is retained for existing automation; prefer \`${root.name()} ${family.compatibilityOf}\` for new workflows.`, '');
112
+ }
113
+ lines.push('| Command | Purpose |', '| --- | --- |', ...nested.map((command) => `| ${commandLabel(command)} | ${tableCell(commandPurpose(command))} |`));
114
+ }
115
+ lines.push('', COMMAND_CATALOG_END);
116
+ return `${lines.join('\n')}\n`;
117
+ }
118
+ function findCommand(root, path) {
119
+ const descriptors = collectCommands(root);
120
+ const fullPath = [root.name(), ...path].join(' ');
121
+ const match = descriptors.find((command) => command.path === fullPath);
122
+ if (!match)
123
+ throw new Error(`user_guide_command_missing:${fullPath}`);
124
+ return match;
125
+ }
126
+ export function renderCapabilityDiscoveryGuide(root) {
127
+ const discoveryCommands = [
128
+ findCommand(root, ['agent', 'tools']),
129
+ findCommand(root, ['agent', 'schema']),
130
+ findCommand(root, ['agent', 'openapi']),
131
+ findCommand(root, ['agent', 'invoke']),
132
+ ];
133
+ const lines = [
134
+ DISCOVERY_GUIDE_START,
135
+ '### Generated capability discovery guide',
136
+ '',
137
+ '> AOPS does not copy a fixed hosted-tool list into this guide. The server catalog is discovered live, so newly registered domain capabilities appear without rewriting prose.',
138
+ '',
139
+ '#### Source-of-truth model',
140
+ '',
141
+ '1. **DCM (Domain Capability Manifest)** is the canonical domain capability source.',
142
+ '2. Host routes, the agent catalog, OpenAPI, JSON Schema, and domain CLI projections are derived views of that capability source.',
143
+ '3. **HRM (Host Registration Manifest)** tells the host how a domain is registered; it is not a second capability source.',
144
+ '4. AOPS sugar commands come from the public Commander program and are cataloged separately above.',
145
+ '',
146
+ '#### Live discovery commands',
147
+ '',
148
+ '| Command | Purpose |',
149
+ '| --- | --- |',
150
+ ...discoveryCommands.map((command) => `| ${commandLabel(command)} | ${tableCell(commandPurpose(command))} |`),
151
+ '',
152
+ 'Use the smallest useful read:',
153
+ '',
154
+ '```bash',
155
+ 'aops agent tools --domain <domain> --summary --json',
156
+ 'aops agent schema --tool <tool-id> --summary --json',
157
+ 'aops agent openapi --domain <domain> --out ./openapi.json',
158
+ '```',
159
+ '',
160
+ DISCOVERY_GUIDE_END,
161
+ ];
162
+ return `${lines.join('\n')}\n`;
163
+ }
164
+ export function renderDocmanCommandCatalog(root) {
165
+ const prefix = `${root.name()} doc`;
166
+ const commands = collectCommands(root).filter((command) => command.path === prefix || command.path.startsWith(`${prefix} `));
167
+ if (commands.length === 0)
168
+ throw new Error(`user_guide_command_missing:${prefix}`);
169
+ const lines = [
170
+ DOCMAN_COMMAND_CATALOG_START,
171
+ '### Generated Docman command catalog',
172
+ '',
173
+ '> This appendix is generated from the public `aops doc` Commander registrations. Do not edit it by hand; regenerate it with `aops docs user-guide --guide docman`.',
174
+ '',
175
+ '| Command | Purpose |',
176
+ '| --- | --- |',
177
+ ...commands.map((command) => `| ${commandLabel(command)} | ${tableCell(commandPurpose(command))} |`),
178
+ '',
179
+ DOCMAN_COMMAND_CATALOG_END,
180
+ ];
181
+ return `${lines.join('\n')}\n`;
182
+ }
183
+ export function renderDocmanDiscoveryGuide(root) {
184
+ const commands = [
185
+ findCommand(root, ['doc', 'outline', 'get']),
186
+ findCommand(root, ['doc', 'index', 'build']),
187
+ findCommand(root, ['doc', 'summary', 'build']),
188
+ findCommand(root, ['doc', 'search']),
189
+ findCommand(root, ['doc', 'scope', 'search']),
190
+ findCommand(root, ['doc', 'answer']),
191
+ findCommand(root, ['doc', 'source']),
192
+ findCommand(root, ['doc', 'mirror', 'pull']),
193
+ findCommand(root, ['agent', 'tools']),
194
+ findCommand(root, ['agent', 'schema']),
195
+ ];
196
+ const lines = [
197
+ DOCMAN_DISCOVERY_GUIDE_START,
198
+ '### Generated Docman discovery and retrieval guide',
199
+ '',
200
+ '> Docman operations and schemas are discovered from the running server. This appendix keeps the retrieval gates current without copying a fixed hosted-tool inventory into prose.',
201
+ '',
202
+ '| Command | Purpose |',
203
+ '| --- | --- |',
204
+ ...commands.map((command) => `| ${commandLabel(command)} | ${tableCell(commandPurpose(command))} |`),
205
+ '',
206
+ 'Use the smallest useful read:',
207
+ '',
208
+ '```bash',
209
+ 'aops doc search --local --q "<keywords>" --ensure summary --json',
210
+ 'aops doc scope search --project-slug <slug> --q "<keywords>" --json',
211
+ 'aops doc answer --document-version-id <id> --q "<question>" --ensure summary --json',
212
+ 'aops agent tools --domain docman --summary --json',
213
+ 'aops agent schema --tool <docman-tool-id> --summary --json',
214
+ '```',
215
+ '',
216
+ DOCMAN_DISCOVERY_GUIDE_END,
217
+ ];
218
+ return `${lines.join('\n')}\n`;
219
+ }
220
+ export function renderChatv3CommandCatalog(root) {
221
+ const prefix = `${root.name()} chat`;
222
+ const commands = collectCommands(root).filter((command) => command.leaf && command.path.startsWith(`${prefix} `));
223
+ if (commands.length === 0)
224
+ throw new Error(`user_guide_command_missing:${prefix}`);
225
+ const lines = [
226
+ CHATV3_COMMAND_CATALOG_START,
227
+ '> This appendix is generated from the public `aops chat` Commander registrations. `aops chatv3` is a compatibility command tree and is not duplicated here. Regenerate with `aops docs user-guide --guide chatv3`.',
228
+ '',
229
+ '| Command | Purpose |',
230
+ '| --- | --- |',
231
+ ...commands.map((command) => `| ${commandLabel(command)} | ${tableCell(commandPurpose(command))} |`),
232
+ '',
233
+ CHATV3_COMMAND_CATALOG_END,
234
+ ];
235
+ return `${lines.join('\n')}\n`;
236
+ }
237
+ export function renderChatv3DiscoveryGuide(root) {
238
+ const commands = [
239
+ findCommand(root, ['agent', 'tools']),
240
+ findCommand(root, ['agent', 'schema']),
241
+ findCommand(root, ['agent', 'invoke']),
242
+ ];
243
+ const lines = [
244
+ CHATV3_DISCOVERY_GUIDE_START,
245
+ '> `aops chat` is the convenience CLI, not the complete ChatV3 domain. Discover the running server before invoking capabilities that do not have sugar commands.',
246
+ '',
247
+ '| Command | Purpose |',
248
+ '| --- | --- |',
249
+ ...commands.map((command) => `| ${commandLabel(command)} | ${tableCell(commandPurpose(command))} |`),
250
+ '',
251
+ 'Use the smallest useful read:',
252
+ '',
253
+ '```bash',
254
+ 'aops chat --help',
255
+ 'aops chat channels --json',
256
+ 'aops chat session list --json',
257
+ 'aops chat read --help',
258
+ 'aops chat listen --help',
259
+ 'aops agent tools --domain chatv3 --summary --json',
260
+ 'aops agent schema --tool <chatv3-tool-id> --summary --json',
261
+ '```',
262
+ '',
263
+ CHATV3_DISCOVERY_GUIDE_END,
264
+ ];
265
+ return `${lines.join('\n')}\n`;
266
+ }
267
+ export function renderAgentspaceCommandCatalog(root) {
268
+ const commands = collectCommands(root);
269
+ const rows = AGENTSPACE_COMMAND_FAMILIES.map((familyName) => {
270
+ const prefix = `${root.name()} ${familyName}`;
271
+ const family = commands.find((command) => command.path === prefix);
272
+ if (!family)
273
+ throw new Error(`user_guide_command_missing:${prefix}`);
274
+ const leaves = commands.filter((command) => command.leaf && command.path.startsWith(`${prefix} `));
275
+ if (leaves.length === 0)
276
+ throw new Error(`user_guide_command_missing:${prefix}:leaf`);
277
+ const leafLabels = leaves
278
+ .map((command) => `\`${command.path.slice(prefix.length + 1)}\``)
279
+ .join(', ');
280
+ return `| ${commandLabel(family)} | ${tableCell(leafLabels)} | ${tableCell(commandPurpose(family))} |`;
281
+ });
282
+ const lines = [
283
+ AGENTSPACE_COMMAND_CATALOG_START,
284
+ '### Generated Agentspace command families',
285
+ '',
286
+ '> This compact appendix is generated from the public Commander registrations. It groups current leaf commands into eleven owner families instead of copying a large command-by-command or hosted-tool catalog. Regenerate it with `aops docs user-guide --guide agentspace`.',
287
+ '',
288
+ '| Family | Registered leaf commands | Purpose |',
289
+ '| --- | --- | --- |',
290
+ ...rows,
291
+ '',
292
+ AGENTSPACE_COMMAND_CATALOG_END,
293
+ ];
294
+ return `${lines.join('\n')}\n`;
295
+ }
296
+ export function renderAgentspaceDiscoveryGuide(root) {
297
+ const commands = [
298
+ findCommand(root, ['skill', 'search']),
299
+ findCommand(root, ['skill', 'ask']),
300
+ findCommand(root, ['agent', 'tools']),
301
+ findCommand(root, ['agent', 'schema']),
302
+ findCommand(root, ['agent', 'invoke']),
303
+ ];
304
+ const lines = [
305
+ AGENTSPACE_DISCOVERY_GUIDE_START,
306
+ '### Generated Agentspace discovery and routing guide',
307
+ '',
308
+ '> Sugar commands cover common Agentspace workflows. The running server catalog remains authoritative for hosted operations, so this guide does not freeze tool ids or tool counts.',
309
+ '',
310
+ '| Command | Purpose |',
311
+ '| --- | --- |',
312
+ ...commands.map((command) => `| ${commandLabel(command)} | ${tableCell(commandPurpose(command))} |`),
313
+ '',
314
+ 'Use the smallest useful read:',
315
+ '',
316
+ '```bash',
317
+ 'aops skill ask --q "<need>" --limit 3 --json',
318
+ 'aops agent tools --domain agentspace --q "<capability>" --limit 20 --summary --json',
319
+ 'aops agent schema --tool <agentspace-tool-id> --summary --json',
320
+ '```',
321
+ '',
322
+ '| Need | Specialized route |',
323
+ '| --- | --- |',
324
+ '| Encrypted coordination and wake | `aops chat` and the `aops-cli-chat` skill |',
325
+ '| Structured decision and consensus | `aops discuss` and the `aops-cli-discuss` skill |',
326
+ '| Tasks, sprints, issues, and review truth | `aops pm` and the `aops-cli-projectman` skill |',
327
+ '| Versioned documents and retrieval | `aops doc` and the `aops-cli-docman` skill |',
328
+ '| File snapshots and lineage | `aops agent tools --domain fileman` and the `aops-cli-fileman` skill |',
329
+ '',
330
+ AGENTSPACE_DISCOVERY_GUIDE_END,
331
+ ];
332
+ return `${lines.join('\n')}\n`;
333
+ }
334
+ export function renderTaskerCommandCatalog(root) {
335
+ const commands = collectCommands(root).filter((command) => command.leaf
336
+ && (command.path.startsWith(`${root.name()} tasker `) || command.path.startsWith(`${root.name()} runner `)));
337
+ if (commands.length === 0)
338
+ throw new Error('user_guide_command_missing:aops tasker-or-runner');
339
+ const lines = [
340
+ TASKER_COMMAND_CATALOG_START,
341
+ '### Generated Tasker and Runner command catalog',
342
+ '',
343
+ '> This compact appendix is generated from the public `aops tasker` and `aops runner` Commander registrations. Do not edit it by hand; regenerate it with `aops docs user-guide --guide tasker`.',
344
+ '',
345
+ '| Command | Purpose |',
346
+ '| --- | --- |',
347
+ ...commands.map((command) => `| ${commandLabel(command)} | ${tableCell(commandPurpose(command))} |`),
348
+ '',
349
+ TASKER_COMMAND_CATALOG_END,
350
+ ];
351
+ return `${lines.join('\n')}\n`;
352
+ }
353
+ export function renderTaskerDiscoveryGuide(root) {
354
+ const commands = [
355
+ findCommand(root, ['agent', 'tools']),
356
+ findCommand(root, ['agent', 'schema']),
357
+ findCommand(root, ['agent', 'invoke']),
358
+ ];
359
+ const lines = [
360
+ TASKER_DISCOVERY_GUIDE_START,
361
+ '### Generated Tasker capability discovery guide',
362
+ '',
363
+ '> Tasker and Runner sugar cover common operator workflows. The running server catalog remains authoritative for the complete hosted capability set, so this guide does not freeze a second tool inventory.',
364
+ '',
365
+ '| Command | Purpose |',
366
+ '| --- | --- |',
367
+ ...commands.map((command) => `| ${commandLabel(command)} | ${tableCell(commandPurpose(command))} |`),
368
+ '',
369
+ 'Use the smallest useful read:',
370
+ '',
371
+ '```bash',
372
+ 'aops tasker --help',
373
+ 'aops runner --help',
374
+ 'aops agent tools --domain tasker --summary --json',
375
+ 'aops agent schema --tool <tasker-tool-id> --summary --json',
376
+ '```',
377
+ '',
378
+ TASKER_DISCOVERY_GUIDE_END,
379
+ ];
380
+ return `${lines.join('\n')}\n`;
381
+ }
382
+ function headingIdentity(line) {
383
+ const match = /^(#{2,6})\s+(?:\d+(?:\.\d+)*\s+)?(.+?)\s*$/u.exec(line);
384
+ if (!match)
385
+ return undefined;
386
+ return `${match[1]}:${match[2]}`;
387
+ }
388
+ function preserveMaterializedHeadingNumbers(existing, rendered) {
389
+ const existingHeadings = new Map();
390
+ for (const line of existing.split('\n')) {
391
+ const identity = headingIdentity(line);
392
+ if (identity)
393
+ existingHeadings.set(identity, line);
394
+ }
395
+ const lines = rendered
396
+ .split('\n')
397
+ .map((line) => existingHeadings.get(headingIdentity(line) ?? '') ?? line);
398
+ const existingLines = existing.split('\n');
399
+ if (existingLines[1] === '' && lines[1] !== '')
400
+ lines.splice(1, 0, '');
401
+ const overviewLine = existingLines.find((line) => headingIdentity(line)?.endsWith(':Overview'));
402
+ const renderedHasOverview = lines.some((line) => headingIdentity(line)?.endsWith(':Overview'));
403
+ if (overviewLine && !renderedHasOverview) {
404
+ const firstHeadingIndex = lines.findIndex((line) => headingIdentity(line) !== undefined);
405
+ if (firstHeadingIndex >= 0)
406
+ lines.splice(firstHeadingIndex + 1, 0, '', overviewLine);
407
+ }
408
+ return lines.join('\n');
409
+ }
410
+ function replaceGeneratedBlock(source, start, end, rendered) {
411
+ const startIndex = source.indexOf(start);
412
+ const endIndex = source.indexOf(end);
413
+ if (startIndex < 0 || endIndex < 0 || endIndex < startIndex) {
414
+ throw new Error(`user_guide_markers_missing_or_invalid:${start}:${end}`);
415
+ }
416
+ if (source.indexOf(start, startIndex + start.length) >= 0 || source.indexOf(end, endIndex + end.length) >= 0) {
417
+ throw new Error(`user_guide_markers_duplicated:${start}:${end}`);
418
+ }
419
+ const existingBlock = source.slice(startIndex, endIndex + end.length);
420
+ const compatibleRendered = preserveMaterializedHeadingNumbers(existingBlock, rendered);
421
+ return `${source.slice(0, startIndex)}${compatibleRendered.trimEnd()}${source.slice(endIndex + end.length)}`;
422
+ }
423
+ function findAppendicesIndex(source) {
424
+ const match = /^## (?:\d+(?:\.\d+)* )?Appendices\s*$/mu.exec(source);
425
+ return match?.index ?? -1;
426
+ }
427
+ function assertGeneratedSectionsAreAppendices(source, commandMarker, discoveryMarker) {
428
+ const appendicesIndex = findAppendicesIndex(source);
429
+ const commandIndex = source.indexOf(commandMarker);
430
+ const discoveryIndex = source.indexOf(discoveryMarker);
431
+ if (appendicesIndex < 0) {
432
+ throw new Error('user_guide_generated_sections_must_be_appendices');
433
+ }
434
+ if (commandIndex < 0 || discoveryIndex < 0)
435
+ return;
436
+ if (commandIndex < appendicesIndex || discoveryIndex < commandIndex) {
437
+ throw new Error('user_guide_generated_sections_must_be_appendices');
438
+ }
439
+ const nextTopLevelSection = source.indexOf('\n## ', appendicesIndex + APPENDICES_HEADING.length);
440
+ if (nextTopLevelSection >= 0 && (commandIndex > nextTopLevelSection || discoveryIndex > nextTopLevelSection)) {
441
+ throw new Error('user_guide_generated_sections_must_be_appendices');
442
+ }
443
+ }
444
+ export function renderGeneratedUserGuideSections(root) {
445
+ return `${renderCommandCatalog(root)}\n${renderCapabilityDiscoveryGuide(root)}`;
446
+ }
447
+ export function refreshGeneratedUserGuideSections(source, root) {
448
+ assertGeneratedSectionsAreAppendices(source, COMMAND_CATALOG_START, DISCOVERY_GUIDE_START);
449
+ const withCommands = replaceGeneratedBlock(source, COMMAND_CATALOG_START, COMMAND_CATALOG_END, renderCommandCatalog(root));
450
+ const refreshed = replaceGeneratedBlock(withCommands, DISCOVERY_GUIDE_START, DISCOVERY_GUIDE_END, renderCapabilityDiscoveryGuide(root));
451
+ return refreshed.endsWith('\n') ? refreshed : `${refreshed}\n`;
452
+ }
453
+ export function renderGeneratedDocmanGuideSections(root) {
454
+ return `${renderDocmanCommandCatalog(root)}\n${renderDocmanDiscoveryGuide(root)}`;
455
+ }
456
+ export function refreshGeneratedDocmanGuideSections(source, root) {
457
+ assertGeneratedSectionsAreAppendices(source, DOCMAN_COMMAND_CATALOG_START, DOCMAN_DISCOVERY_GUIDE_START);
458
+ const withCommands = replaceGeneratedBlock(source, DOCMAN_COMMAND_CATALOG_START, DOCMAN_COMMAND_CATALOG_END, renderDocmanCommandCatalog(root));
459
+ const refreshed = replaceGeneratedBlock(withCommands, DOCMAN_DISCOVERY_GUIDE_START, DOCMAN_DISCOVERY_GUIDE_END, renderDocmanDiscoveryGuide(root));
460
+ return refreshed.endsWith('\n') ? refreshed : `${refreshed}\n`;
461
+ }
462
+ export function renderGeneratedChatv3GuideSections(root) {
463
+ return `${renderChatv3CommandCatalog(root)}\n${renderChatv3DiscoveryGuide(root)}`;
464
+ }
465
+ export function refreshGeneratedChatv3GuideSections(source, root) {
466
+ assertGeneratedSectionsAreAppendices(source, CHATV3_COMMAND_CATALOG_START, CHATV3_DISCOVERY_GUIDE_START);
467
+ const withCommands = replaceGeneratedBlock(source, CHATV3_COMMAND_CATALOG_START, CHATV3_COMMAND_CATALOG_END, renderChatv3CommandCatalog(root));
468
+ const refreshed = replaceGeneratedBlock(withCommands, CHATV3_DISCOVERY_GUIDE_START, CHATV3_DISCOVERY_GUIDE_END, renderChatv3DiscoveryGuide(root));
469
+ return refreshed.endsWith('\n') ? refreshed : `${refreshed}\n`;
470
+ }
471
+ export function renderGeneratedAgentspaceGuideSections(root) {
472
+ return `${renderAgentspaceCommandCatalog(root)}\n${renderAgentspaceDiscoveryGuide(root)}`;
473
+ }
474
+ export function refreshGeneratedAgentspaceGuideSections(source, root) {
475
+ assertGeneratedSectionsAreAppendices(source, AGENTSPACE_COMMAND_CATALOG_START, AGENTSPACE_DISCOVERY_GUIDE_START);
476
+ const withCommands = replaceGeneratedBlock(source, AGENTSPACE_COMMAND_CATALOG_START, AGENTSPACE_COMMAND_CATALOG_END, renderAgentspaceCommandCatalog(root));
477
+ const refreshed = replaceGeneratedBlock(withCommands, AGENTSPACE_DISCOVERY_GUIDE_START, AGENTSPACE_DISCOVERY_GUIDE_END, renderAgentspaceDiscoveryGuide(root));
478
+ return refreshed.endsWith('\n') ? refreshed : `${refreshed}\n`;
479
+ }
480
+ export function renderGeneratedTaskerGuideSections(root) {
481
+ return `${renderTaskerCommandCatalog(root)}\n${renderTaskerDiscoveryGuide(root)}`;
482
+ }
483
+ export function refreshGeneratedTaskerGuideSections(source, root) {
484
+ assertGeneratedSectionsAreAppendices(source, TASKER_COMMAND_CATALOG_START, TASKER_DISCOVERY_GUIDE_START);
485
+ const withCommands = replaceGeneratedBlock(source, TASKER_COMMAND_CATALOG_START, TASKER_COMMAND_CATALOG_END, renderTaskerCommandCatalog(root));
486
+ const refreshed = replaceGeneratedBlock(withCommands, TASKER_DISCOVERY_GUIDE_START, TASKER_DISCOVERY_GUIDE_END, renderTaskerDiscoveryGuide(root));
487
+ return refreshed.endsWith('\n') ? refreshed : `${refreshed}\n`;
488
+ }
package/dist/main.js CHANGED
@@ -39,6 +39,10 @@ import { makeTargetCommand } from './commands/target.js';
39
39
  import { makeVersionCommand } from './commands/version.js';
40
40
  import { makeCodexCommand } from './commands/codex.js';
41
41
  import { makeGlobalUpdateCommand } from './commands/global-update.js';
42
+ import { makeDocsCommand } from './commands/docs.js';
43
+ import { makeLoopCommand } from './commands/loop.js';
44
+ import { makeTaskerCommand } from './commands/tasker.js';
45
+ import { makeRunnerCommand } from './commands/runner.js';
42
46
  import { launchBundledTui, shouldLaunchBundledTui } from './lib/tui-launcher.js';
43
47
  import { CommunityDiagnosticError, formatCommunityDiagnostic, } from './lib/community-diagnostic.js';
44
48
  import { resolveCliApiBaseUrl } from './utils/api.js';
@@ -56,7 +60,7 @@ function renderTrustedLocalLicenseStatus(command) {
56
60
  profile: 'trusted-local',
57
61
  commercialAvailable: false,
58
62
  southRequired: false,
59
- builtInDomains: ['agentspace', 'chatv3', 'docman', 'projectman', 'sys'],
63
+ builtInDomains: ['agentspace', 'chatv3', 'docman', 'projectman', 'sys', 'tasker'],
60
64
  next: 'South-backed licensing and external domains are not available in this public profile.',
61
65
  };
62
66
  const json = command.optsWithGlobals().json === true;
@@ -157,9 +161,13 @@ export function buildCommunityProgram() {
157
161
  program.addCommand(makeVersionCommand());
158
162
  program.addCommand(makeCodexCommand());
159
163
  program.addCommand(makeGlobalUpdateCommand());
164
+ program.addCommand(makeDocsCommand(() => program));
165
+ program.addCommand(makeLoopCommand());
166
+ program.addCommand(makeTaskerCommand());
167
+ program.addCommand(makeRunnerCommand());
160
168
  program.addHelpText('after', `
161
169
  AOPS Community is a single-user, self-hosted/local-trusted distribution.
162
- Canonical writes go to the local AOPS server; .aops/** remains a read-only cache.
170
+ Canonical writes go to the local AOPS server; generated mirrors and views live under the read-only .aops-cache/** tree.
163
171
 
164
172
  Quick checks:
165
173
  aops setup ai
@@ -3,7 +3,7 @@ export const AOPS_AGENTS_MD_TEMPLATE_SEEDS = [
3
3
  slug: 'aops-collaborative-startup',
4
4
  title: 'AOPS Collaborative Startup',
5
5
  description: 'Default solo-first session starter; boots the aops-collaborative-work skill (collaboration and chat are operator-opt-in).',
6
- mirrorPath: '.aops/hosted/prompts/aops-collaborative-startup.md',
6
+ mirrorPath: '.aops-cache/hosted/prompts/aops-collaborative-startup.md',
7
7
  promptRef: 'prompt:aops-collaborative-startup',
8
8
  tags: ['default', 'starter', 'solo-first', 'coordination-optional'],
9
9
  snippet: [
@@ -22,7 +22,7 @@ export const AOPS_AGENTS_MD_TEMPLATE_SEEDS = [
22
22
  slug: 'aops-task-execution-template',
23
23
  title: 'AOPS Task Execution Template',
24
24
  description: 'Operator-fillable, PM-backed generic execution checklist template.',
25
- mirrorPath: '.aops/hosted/prompts/aops-task-execution-template.md',
25
+ mirrorPath: '.aops-cache/hosted/prompts/aops-task-execution-template.md',
26
26
  promptRef: 'prompt:aops-task-execution-template',
27
27
  tags: ['pm', 'closeout', 'template'],
28
28
  snippet: [
@@ -37,7 +37,7 @@ export const AOPS_AGENTS_MD_TEMPLATE_SEEDS = [
37
37
  slug: 'aops-cli-discuss',
38
38
  title: 'AOPS Discuss / Decision Protocol',
39
39
  description: 'Standalone discuss decision/consensus discipline; coordination via aops-cli-chat, review via aops-cli-projectman; canonical mechanics in the aops-cli-discuss hosted skill.',
40
- mirrorPath: '.aops/hosted/skills/aops-cli-discuss.md',
40
+ mirrorPath: '.aops-cache/hosted/skills/aops-cli-discuss.md',
41
41
  promptRef: 'skill:aops-cli-discuss',
42
42
  tags: ['discuss', 'decision', 'consensus'],
43
43
  snippet: [
@@ -236,7 +236,7 @@ export async function updateAgentsMdFile(options = {}) {
236
236
  throw new Error('This command updates AGENTS.md. Retry with --apply or use --preview.');
237
237
  }
238
238
  if (options.preview === true && options.syncHosted === true) {
239
- throw new Error('--sync-hosted mutates .aops/hosted mirrors. Use `aops-cli agents-md update --sync-hosted --apply`.');
239
+ throw new Error('--sync-hosted mutates .aops-cache/hosted mirrors. Use `aops-cli agents-md update --sync-hosted --apply`.');
240
240
  }
241
241
  const target = resolveAgentsMdTarget(options.root);
242
242
  const selectedTemplates = selectAgentsMdTemplates(options);
@@ -4,26 +4,26 @@ import { fileURLToPath } from 'node:url';
4
4
  const PACKAGE_ROOT_URL = new URL('../../', import.meta.url);
5
5
  const GUIDE_TARGETS = {
6
6
  operator: {
7
- mirrorPath: path.join('.aops', 'docman', 'aops-guides', 'aops-cli-user-guide.md'),
7
+ mirrorPath: path.join('.aops-cache', 'docman', 'aops-guides', 'aops-cli-user-guide.md'),
8
8
  },
9
9
  agentspace: {
10
- mirrorPath: path.join('.aops', 'docman', 'domain-guides', 'agentspace-user-guide.md'),
10
+ mirrorPath: path.join('.aops-cache', 'docman', 'domain-guides', 'agentspace-user-guide.md'),
11
11
  },
12
12
  projectman: {
13
- mirrorPath: path.join('.aops', 'docman', 'domain-guides', 'projectman-user-guide.md'),
13
+ mirrorPath: path.join('.aops-cache', 'docman', 'domain-guides', 'projectman-user-guide.md'),
14
14
  },
15
15
  docman: {
16
- mirrorPath: path.join('.aops', 'docman', 'domain-guides', 'docman-user-guide.md'),
16
+ mirrorPath: path.join('.aops-cache', 'docman', 'domain-guides', 'docman-user-guide.md'),
17
17
  },
18
18
  fileman: {
19
- mirrorPath: path.join('.aops', 'docman', 'domain-guides', 'fileman-user-guide.md'),
19
+ mirrorPath: path.join('.aops-cache', 'docman', 'domain-guides', 'fileman-user-guide.md'),
20
20
  },
21
21
  tasker: {
22
- mirrorPath: path.join('.aops', 'docman', 'domain-guides', 'tasker-user-guide.md'),
22
+ mirrorPath: path.join('.aops-cache', 'docman', 'domain-guides', 'tasker-user-guide.md'),
23
23
  },
24
24
  agentAssets: {
25
25
  fallbackPath: './docs/agent-assets-bootstrap.md',
26
- mirrorPath: path.join('.aops', 'docman', 'aops-guides', 'aops-agent-assets-bootstrap.md'),
26
+ mirrorPath: path.join('.aops-cache', 'docman', 'aops-guides', 'aops-agent-assets-bootstrap.md'),
27
27
  },
28
28
  };
29
29
  function resolvePackagePath(relativePath) {
@@ -2,6 +2,7 @@ import fs from 'node:fs/promises';
2
2
  import path from 'node:path';
3
3
  import { normalizeNonEmpty } from './command.js';
4
4
  import { parseFrontmatterDocument, renderFrontmatterDocument } from './memory-workspace.js';
5
+ import { resolveAopsCacheRoot } from './repo-first-storage.js';
5
6
  import { writeFileWithRetry } from './transient-fs.js';
6
7
  function slugify(value) {
7
8
  return value
@@ -98,7 +99,7 @@ function hostedProjectKeyFromFrontmatter(frontmatter) {
98
99
  });
99
100
  }
100
101
  export function resolveHostedWorkspacePaths(repoRoot) {
101
- const root = path.join(repoRoot, '.aops', 'hosted');
102
+ const root = path.join(resolveAopsCacheRoot(repoRoot), 'hosted');
102
103
  return {
103
104
  root,
104
105
  skillsRoot: path.join(root, 'skills'),
@@ -1,13 +1,38 @@
1
+ import fs from 'node:fs/promises';
1
2
  import path from 'node:path';
2
3
  import { normalizeNonEmpty } from './command.js';
4
+ import { writeFileWithRetry } from './transient-fs.js';
5
+ export const AOPS_CONTROL_DIR = '.aops';
6
+ export const AOPS_CACHE_DIR = '.aops-cache';
7
+ export const AOPS_PRIVATE_GITIGNORE_ENTRIES = [`/${AOPS_CONTROL_DIR}/`, `/${AOPS_CACHE_DIR}/`];
3
8
  export function resolveRepoFirstWorkspaceRoot(context) {
4
9
  const repoRoot = typeof context === 'string' ? context : context.repoRoot;
5
10
  const localRoot = typeof context === 'string' ? undefined : normalizeNonEmpty(context.localRoot);
6
11
  if (!localRoot)
7
- return path.join(repoRoot, '.aops');
12
+ return path.join(repoRoot, AOPS_CACHE_DIR);
8
13
  return path.isAbsolute(localRoot) ? localRoot : path.join(repoRoot, localRoot);
9
14
  }
10
15
  export function resolveRepoFirstWorkspaceRelativeRoot(context) {
11
16
  const repoRoot = typeof context === 'string' ? context : context.repoRoot;
12
17
  return path.relative(repoRoot, resolveRepoFirstWorkspaceRoot(context)).split(path.sep).join('/') || '.';
13
18
  }
19
+ export function resolveAopsCacheRoot(repoRoot) {
20
+ return path.join(repoRoot, AOPS_CACHE_DIR);
21
+ }
22
+ export async function ensureAopsPrivatePathsIgnored(repoRoot) {
23
+ const gitignorePath = path.join(repoRoot, '.gitignore');
24
+ let content = '';
25
+ try {
26
+ content = await fs.readFile(gitignorePath, 'utf8');
27
+ }
28
+ catch {
29
+ content = '';
30
+ }
31
+ const lines = new Set(content.split(/\r?\n/));
32
+ const missing = AOPS_PRIVATE_GITIGNORE_ENTRIES.filter((entry) => !lines.has(entry));
33
+ if (missing.length === 0)
34
+ return;
35
+ const prefix = content.trimEnd();
36
+ const next = `${prefix}${prefix ? '\n' : ''}${missing.join('\n')}\n`;
37
+ await writeFileWithRetry(gitignorePath, next, 'utf8');
38
+ }