@tacuchi/agent-workflow-cli 22.4.2 → 24.0.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 (295) hide show
  1. package/README.md +39 -3
  2. package/dist/adapters/git-cli.js +59 -17
  3. package/dist/adapters/git-cli.js.map +1 -1
  4. package/dist/adapters/node-file-system.js +55 -1
  5. package/dist/adapters/node-file-system.js.map +1 -1
  6. package/dist/adapters/postgres-readonly-tools.js +277 -0
  7. package/dist/adapters/postgres-readonly-tools.js.map +1 -0
  8. package/dist/application/artifacts-service.js +2 -2
  9. package/dist/application/artifacts-service.js.map +1 -1
  10. package/dist/application/capability/dispatcher.js +2 -2
  11. package/dist/application/capability/dispatcher.js.map +1 -1
  12. package/dist/application/capability/installed-inventory.js +2 -2
  13. package/dist/application/capability/installed-inventory.js.map +1 -1
  14. package/dist/application/capability/readiness.js +1 -1
  15. package/dist/application/capability/readiness.js.map +1 -1
  16. package/dist/application/check-branch-service.js +2 -2
  17. package/dist/application/check-branch-service.js.map +1 -1
  18. package/dist/application/checkpoint/files-touched.js +271 -0
  19. package/dist/application/checkpoint/files-touched.js.map +1 -0
  20. package/dist/application/checkpoint/markdown.js +61 -8
  21. package/dist/application/checkpoint/markdown.js.map +1 -1
  22. package/dist/application/checkpoint/state-reader.js +8 -2
  23. package/dist/application/checkpoint/state-reader.js.map +1 -1
  24. package/dist/application/checkpoint-write-service.js +16 -5
  25. package/dist/application/checkpoint-write-service.js.map +1 -1
  26. package/dist/application/claims-ledger.js +330 -0
  27. package/dist/application/claims-ledger.js.map +1 -0
  28. package/dist/application/claims-recovery.js +338 -0
  29. package/dist/application/claims-recovery.js.map +1 -0
  30. package/dist/application/database-mcp-server.js +168 -0
  31. package/dist/application/database-mcp-server.js.map +1 -0
  32. package/dist/application/database-mcp-stdio.js +137 -0
  33. package/dist/application/database-mcp-stdio.js.map +1 -0
  34. package/dist/application/database-tool-catalog.js +226 -0
  35. package/dist/application/database-tool-catalog.js.map +1 -0
  36. package/dist/application/dev-only-services.js +154 -44
  37. package/dist/application/dev-only-services.js.map +1 -1
  38. package/dist/application/dsn-reader-service.js +1 -1
  39. package/dist/application/elicitation-server.js +382 -0
  40. package/dist/application/elicitation-server.js.map +1 -0
  41. package/dist/application/elicitation-stdio.js +48 -0
  42. package/dist/application/elicitation-stdio.js.map +1 -0
  43. package/dist/application/flow/advance.js +86 -5
  44. package/dist/application/flow/advance.js.map +1 -1
  45. package/dist/application/flow/checkout-observation.js +152 -0
  46. package/dist/application/flow/checkout-observation.js.map +1 -0
  47. package/dist/application/flow/flow-service.js +72 -13
  48. package/dist/application/flow/flow-service.js.map +1 -1
  49. package/dist/application/flow/internal-actions.js +460 -1
  50. package/dist/application/flow/internal-actions.js.map +1 -1
  51. package/dist/application/flow/internal-drive.js +22 -9
  52. package/dist/application/flow/internal-drive.js.map +1 -1
  53. package/dist/application/flow/prove.js +205 -0
  54. package/dist/application/flow/prove.js.map +1 -0
  55. package/dist/application/flow/run-journey.js +15 -0
  56. package/dist/application/flow/run-journey.js.map +1 -0
  57. package/dist/application/flow/run-projection.js +15 -3
  58. package/dist/application/flow/run-projection.js.map +1 -1
  59. package/dist/application/flow/run-state-service.js +19 -4
  60. package/dist/application/flow/run-state-service.js.map +1 -1
  61. package/dist/application/flow/submit.js +250 -72
  62. package/dist/application/flow/submit.js.map +1 -1
  63. package/dist/application/generate-launch-service.js +4 -4
  64. package/dist/application/generate-launch-service.js.map +1 -1
  65. package/dist/application/git-flow-service.js +9 -0
  66. package/dist/application/git-flow-service.js.map +1 -1
  67. package/dist/application/local-proposal.js +9 -0
  68. package/dist/application/local-proposal.js.map +1 -1
  69. package/dist/application/lock-service.js +96 -28
  70. package/dist/application/lock-service.js.map +1 -1
  71. package/dist/application/logging/log-events.js +19 -3
  72. package/dist/application/logging/log-events.js.map +1 -1
  73. package/dist/application/logging/logger.js +2 -2
  74. package/dist/application/logging/logger.js.map +1 -1
  75. package/dist/application/mcp-connections-service.js +115 -41
  76. package/dist/application/mcp-connections-service.js.map +1 -1
  77. package/dist/application/mcp-doctor-service.js +98 -54
  78. package/dist/application/mcp-doctor-service.js.map +1 -1
  79. package/dist/application/mcp-entry-classification.js +60 -0
  80. package/dist/application/mcp-entry-classification.js.map +1 -0
  81. package/dist/application/mcp-host-reader.js +114 -81
  82. package/dist/application/mcp-host-reader.js.map +1 -1
  83. package/dist/application/mcp-host-receipt-service.js +399 -0
  84. package/dist/application/mcp-host-receipt-service.js.map +1 -0
  85. package/dist/application/mcp-host-receipt-store.js +122 -0
  86. package/dist/application/mcp-host-receipt-store.js.map +1 -0
  87. package/dist/application/mcp-host-receipts.js +28 -0
  88. package/dist/application/mcp-host-receipts.js.map +1 -0
  89. package/dist/application/mcp-host-writer.js +321 -126
  90. package/dist/application/mcp-host-writer.js.map +1 -1
  91. package/dist/application/mcp-launch-probe-service.js +142 -0
  92. package/dist/application/mcp-launch-probe-service.js.map +1 -0
  93. package/dist/application/mcp-migration-service.js +351 -0
  94. package/dist/application/mcp-migration-service.js.map +1 -0
  95. package/dist/application/mcp-native-host-check-service.js +154 -0
  96. package/dist/application/mcp-native-host-check-service.js.map +1 -0
  97. package/dist/application/mcp-receipt-registration-service.js +105 -0
  98. package/dist/application/mcp-receipt-registration-service.js.map +1 -0
  99. package/dist/application/mcp-receipt-removal-service.js +62 -0
  100. package/dist/application/mcp-receipt-removal-service.js.map +1 -0
  101. package/dist/application/mcp-remove-service.js +84 -21
  102. package/dist/application/mcp-remove-service.js.map +1 -1
  103. package/dist/application/mcp-scope-common.js +2 -4
  104. package/dist/application/mcp-scope-common.js.map +1 -1
  105. package/dist/application/mcp-setup-service.js +60 -21
  106. package/dist/application/mcp-setup-service.js.map +1 -1
  107. package/dist/application/mcp-stdio-probe.js +526 -0
  108. package/dist/application/mcp-stdio-probe.js.map +1 -0
  109. package/dist/application/mcp-test-connection-service.js +23 -50
  110. package/dist/application/mcp-test-connection-service.js.map +1 -1
  111. package/dist/application/merge-state-service.js +10 -16
  112. package/dist/application/merge-state-service.js.map +1 -1
  113. package/dist/application/multiroot/claude.js +34 -15
  114. package/dist/application/multiroot/claude.js.map +1 -1
  115. package/dist/application/multiroot/codex.js +9 -5
  116. package/dist/application/multiroot/codex.js.map +1 -1
  117. package/dist/application/multiroot-service.js +20 -11
  118. package/dist/application/multiroot-service.js.map +1 -1
  119. package/dist/application/parsers/project-block.js +25 -2
  120. package/dist/application/parsers/project-block.js.map +1 -1
  121. package/dist/application/paths-service.js +30 -31
  122. package/dist/application/paths-service.js.map +1 -1
  123. package/dist/application/plan-exec-batch-service.js +549 -0
  124. package/dist/application/plan-exec-batch-service.js.map +1 -0
  125. package/dist/application/plan-exec-decision-service.js +273 -0
  126. package/dist/application/plan-exec-decision-service.js.map +1 -0
  127. package/dist/application/project-md-service.js +2 -2
  128. package/dist/application/project-md-service.js.map +1 -1
  129. package/dist/application/project-md-upsert-service.js +4 -4
  130. package/dist/application/project-md-upsert-service.js.map +1 -1
  131. package/dist/application/project-tab-data.js +12 -7
  132. package/dist/application/project-tab-data.js.map +1 -1
  133. package/dist/application/release-data-service.js +2 -2
  134. package/dist/application/release-data-service.js.map +1 -1
  135. package/dist/application/resume-service.js +32 -11
  136. package/dist/application/resume-service.js.map +1 -1
  137. package/dist/application/retirement/apply.js +84 -0
  138. package/dist/application/retirement/apply.js.map +1 -1
  139. package/dist/application/retirement/attribution.js +31 -1
  140. package/dist/application/retirement/attribution.js.map +1 -1
  141. package/dist/application/retirement/graph.js +19 -1
  142. package/dist/application/retirement/graph.js.map +1 -1
  143. package/dist/application/retirement/journal.js +11 -0
  144. package/dist/application/retirement/journal.js.map +1 -1
  145. package/dist/application/retirement/prepare.js +89 -3
  146. package/dist/application/retirement/prepare.js.map +1 -1
  147. package/dist/application/retirement/preview.js +16 -0
  148. package/dist/application/retirement/preview.js.map +1 -1
  149. package/dist/application/retirement/resolve.js +65 -0
  150. package/dist/application/retirement/resolve.js.map +1 -1
  151. package/dist/application/self/host-states.js +2 -0
  152. package/dist/application/self/host-states.js.map +1 -1
  153. package/dist/application/self/install-skill.js +21 -17
  154. package/dist/application/self/install-skill.js.map +1 -1
  155. package/dist/application/self/mcp-config.js +392 -84
  156. package/dist/application/self/mcp-config.js.map +1 -1
  157. package/dist/application/self/mcp-via-state.js +62 -0
  158. package/dist/application/self/mcp-via-state.js.map +1 -0
  159. package/dist/application/self/uninstall.js +15 -5
  160. package/dist/application/self/uninstall.js.map +1 -1
  161. package/dist/application/session-close-service.js +24 -1
  162. package/dist/application/session-close-service.js.map +1 -1
  163. package/dist/application/session-create-service.js +7 -0
  164. package/dist/application/session-create-service.js.map +1 -1
  165. package/dist/application/session-resume-service.js +2 -2
  166. package/dist/application/session-resume-service.js.map +1 -1
  167. package/dist/application/sessions-service.js +2 -4
  168. package/dist/application/sessions-service.js.map +1 -1
  169. package/dist/application/skills-resolver-service.js +4 -4
  170. package/dist/application/skills-resolver-service.js.map +1 -1
  171. package/dist/application/source-boundary-policy.js +18 -7
  172. package/dist/application/source-boundary-policy.js.map +1 -1
  173. package/dist/application/source-remove-service.js +12 -1
  174. package/dist/application/source-remove-service.js.map +1 -1
  175. package/dist/application/sources-service.js +2 -2
  176. package/dist/application/sources-service.js.map +1 -1
  177. package/dist/application/status-service.js +4 -0
  178. package/dist/application/status-service.js.map +1 -1
  179. package/dist/application/visibility-doctor-service.js +1 -1
  180. package/dist/application/visibility-doctor-service.js.map +1 -1
  181. package/dist/application/workline-index-service.js +182 -27
  182. package/dist/application/workline-index-service.js.map +1 -1
  183. package/dist/application/workspace-init-service.js +89 -271
  184. package/dist/application/workspace-init-service.js.map +1 -1
  185. package/dist/application/workspace-materialization-service.js +300 -0
  186. package/dist/application/workspace-materialization-service.js.map +1 -0
  187. package/dist/application/worktree-service.js +32 -3
  188. package/dist/application/worktree-service.js.map +1 -1
  189. package/dist/cli/commands/capability.js +4 -7
  190. package/dist/cli/commands/capability.js.map +1 -1
  191. package/dist/cli/commands/claims.js +72 -0
  192. package/dist/cli/commands/claims.js.map +1 -0
  193. package/dist/cli/commands/dev-only.js +73 -25
  194. package/dist/cli/commands/dev-only.js.map +1 -1
  195. package/dist/cli/commands/flow.js +145 -42
  196. package/dist/cli/commands/flow.js.map +1 -1
  197. package/dist/cli/commands/index.js +4 -0
  198. package/dist/cli/commands/index.js.map +1 -1
  199. package/dist/cli/commands/mcp.js +752 -76
  200. package/dist/cli/commands/mcp.js.map +1 -1
  201. package/dist/cli/commands/multiroot.js +40 -7
  202. package/dist/cli/commands/multiroot.js.map +1 -1
  203. package/dist/cli/commands/resume.js +9 -3
  204. package/dist/cli/commands/resume.js.map +1 -1
  205. package/dist/cli/commands/retirement.js +9 -0
  206. package/dist/cli/commands/retirement.js.map +1 -1
  207. package/dist/cli/commands/session-create.js +1 -1
  208. package/dist/cli/commands/session-create.js.map +1 -1
  209. package/dist/cli/commands/skills.js +1 -1
  210. package/dist/cli/commands/skills.js.map +1 -1
  211. package/dist/cli/commands/status.js +72 -24
  212. package/dist/cli/commands/status.js.map +1 -1
  213. package/dist/cli/commands/tool.js +141 -0
  214. package/dist/cli/commands/tool.js.map +1 -0
  215. package/dist/cli/commands/workspace-init.js +5 -5
  216. package/dist/cli/commands/workspace-init.js.map +1 -1
  217. package/dist/cli/help-groups.js +6 -1
  218. package/dist/cli/help-groups.js.map +1 -1
  219. package/dist/cli/main.js +272 -67
  220. package/dist/cli/main.js.map +1 -1
  221. package/dist/cli/parser.js +8 -1
  222. package/dist/cli/parser.js.map +1 -1
  223. package/dist/cli/registry.js.map +1 -1
  224. package/dist/cli/render.js +15 -2
  225. package/dist/cli/render.js.map +1 -1
  226. package/dist/cli/tui/app.js +3 -2
  227. package/dist/cli/tui/app.js.map +1 -1
  228. package/dist/cli/tui/components/workspace-init-form.js +7 -7
  229. package/dist/cli/tui/components/workspace-init-form.js.map +1 -1
  230. package/dist/cli/tui/data/workflow-content.js +2 -2
  231. package/dist/cli/tui/data/workflow-content.js.map +1 -1
  232. package/dist/cli/tui/tabs/config-tab.js +4 -3
  233. package/dist/cli/tui/tabs/config-tab.js.map +1 -1
  234. package/dist/cli/tui/tabs/mcp-tab-helpers.js +72 -1
  235. package/dist/cli/tui/tabs/mcp-tab-helpers.js.map +1 -1
  236. package/dist/cli/tui/tabs/mcp-tab.js +101 -42
  237. package/dist/cli/tui/tabs/mcp-tab.js.map +1 -1
  238. package/dist/cli/tui/tabs/project-tab.js +18 -21
  239. package/dist/cli/tui/tabs/project-tab.js.map +1 -1
  240. package/dist/cli/tui/workspace-root.js +13 -0
  241. package/dist/cli/tui/workspace-root.js.map +1 -0
  242. package/dist/domain/capability/protocol.js +2 -2
  243. package/dist/domain/capability/protocol.js.map +1 -1
  244. package/dist/domain/database-tools.js +445 -0
  245. package/dist/domain/database-tools.js.map +1 -0
  246. package/dist/domain/degradation-notice.js +60 -0
  247. package/dist/domain/degradation-notice.js.map +1 -0
  248. package/dist/domain/elicitation.js +152 -0
  249. package/dist/domain/elicitation.js.map +1 -0
  250. package/dist/domain/flow/answer.js +173 -42
  251. package/dist/domain/flow/answer.js.map +1 -1
  252. package/dist/domain/flow/authority.js +184 -127
  253. package/dist/domain/flow/authority.js.map +1 -1
  254. package/dist/domain/flow/directive.js +47 -1
  255. package/dist/domain/flow/directive.js.map +1 -1
  256. package/dist/domain/flow/rules.js +7 -4
  257. package/dist/domain/flow/rules.js.map +1 -1
  258. package/dist/domain/flow/run-state.js +636 -31
  259. package/dist/domain/flow/run-state.js.map +1 -1
  260. package/dist/domain/harnesses.js +16 -0
  261. package/dist/domain/harnesses.js.map +1 -1
  262. package/dist/domain/mcp-entry.js +164 -28
  263. package/dist/domain/mcp-entry.js.map +1 -1
  264. package/dist/domain/postgres-object-search.js +320 -0
  265. package/dist/domain/postgres-object-search.js.map +1 -0
  266. package/dist/domain/redaction.js +47 -0
  267. package/dist/domain/redaction.js.map +1 -0
  268. package/dist/domain/retirement/proposal.js +1 -0
  269. package/dist/domain/retirement/proposal.js.map +1 -1
  270. package/dist/domain/structured-choice-stamp.js +32 -4
  271. package/dist/domain/structured-choice-stamp.js.map +1 -1
  272. package/dist/domain/workline-mcp-entry.js +34 -0
  273. package/dist/domain/workline-mcp-entry.js.map +1 -0
  274. package/dist/ports/postgres-tools.js +10 -0
  275. package/dist/ports/postgres-tools.js.map +1 -0
  276. package/dist/runtime/namespace-resolver.js +104 -18
  277. package/dist/runtime/namespace-resolver.js.map +1 -1
  278. package/package.json +5 -1
  279. package/skills/w/README.md +2 -2
  280. package/skills/w/SKILL.md +9 -10
  281. package/skills/w/artifacts/README.md +1 -1
  282. package/skills/w/commands/README.md +3 -3
  283. package/skills/w/commands/persist.md +3 -1
  284. package/skills/w/commands/resume.md +1 -1
  285. package/skills/w/commands/spec-new.md +2 -2
  286. package/skills/w/commands/status.md +1 -1
  287. package/skills/w/commands/workspace-init.md +9 -10
  288. package/skills/w/context/MANIFEST.json +1 -4
  289. package/skills/w/harness/HARNESS.md +1 -1
  290. package/skills/w/loops/quick-loop/LOOP.md +1 -1
  291. package/skills/w/modules/PROMPT-CONTINUITY.md +1 -1
  292. package/skills/w/modules/WORKSPACE-SCAFFOLD.md +17 -20
  293. package/skills/w/schemas/capability-descriptor.schema.json +1 -1
  294. package/dist/application/mcp-dbhub-launcher.js +0 -216
  295. package/dist/application/mcp-dbhub-launcher.js.map +0 -1
@@ -1,5 +1,16 @@
1
- import { join } from "node:path";
1
+ import { dirname, join } from "node:path";
2
2
  import { NAMESPACE_REGEX, normalizeNamespace } from "./namespace.js";
3
+ export class WorklineDirectoryError extends Error {
4
+ root;
5
+ namespaces;
6
+ code = "WORKLINE_NAMESPACE_AMBIGUOUS";
7
+ constructor(root, namespaces) {
8
+ super(`More than one Workline namespace is materialized at ${root}: ${namespaces.join(", ")}. Pass --namespace <name> (or set AW_NAMESPACE) to select one.`);
9
+ this.root = root;
10
+ this.namespaces = namespaces;
11
+ this.name = "WorklineDirectoryError";
12
+ }
13
+ }
3
14
  export const DEFAULT_NAMESPACE = "workflow";
4
15
  export const ENV_VAR_NAMESPACE = "AW_NAMESPACE";
5
16
  /**
@@ -18,49 +29,124 @@ export class NamespaceResolver {
18
29
  this.env = env;
19
30
  }
20
31
  async resolve(flag) {
32
+ const directory = await this.resolveDirectory(flag);
33
+ return { namespace: directory.namespace, source: directory.namespaceSource };
34
+ }
35
+ /**
36
+ * Resolve both the namespace and the root it scopes. Explicit namespace
37
+ * selection is deliberately honoured before discovery; an explicit request
38
+ * for a different namespace must not be silently redirected by a neighbouring
39
+ * marker. Without an explicit selection, the closest ancestor with one
40
+ * canonical marker wins, while two markers at that same level are a real
41
+ * ambiguity rather than a reason to fall back to a global preference.
42
+ */
43
+ async resolveDirectory(flag) {
44
+ const cwd = this.env.cwd();
21
45
  if (flag !== undefined && flag.trim().length > 0) {
22
- return { namespace: normalizeNamespace(flag), source: "flag" };
46
+ const namespace = normalizeNamespace(flag);
47
+ const root = await this.findMarkerForNamespace(cwd, namespace);
48
+ return {
49
+ root: root ?? cwd,
50
+ namespace,
51
+ namespaceSource: "flag",
52
+ materialized: root !== null,
53
+ };
23
54
  }
24
55
  const envVal = this.env.get(ENV_VAR_NAMESPACE);
25
56
  if (envVal !== undefined && envVal.trim().length > 0) {
26
- return { namespace: normalizeNamespace(envVal), source: "env" };
57
+ const namespace = normalizeNamespace(envVal);
58
+ const root = await this.findMarkerForNamespace(cwd, namespace);
59
+ return {
60
+ root: root ?? cwd,
61
+ namespace,
62
+ namespaceSource: "env",
63
+ materialized: root !== null,
64
+ };
27
65
  }
28
- const workspaceNs = await this.detectFromWorkspace(this.env.cwd());
29
- if (workspaceNs !== null) {
30
- return { namespace: workspaceNs, source: "workspace" };
66
+ const workspace = await this.detectFromWorkspace(cwd);
67
+ if (workspace !== null) {
68
+ return {
69
+ root: workspace.root,
70
+ namespace: workspace.namespace,
71
+ namespaceSource: "workspace",
72
+ materialized: true,
73
+ };
31
74
  }
32
75
  const configPath = namespaceConfigFile(this.env.homeDir());
33
76
  if (await this.fs.exists(configPath)) {
34
77
  const raw = await this.fs.readText(configPath);
35
- return { namespace: normalizeNamespace(raw), source: "config" };
78
+ const namespace = normalizeNamespace(raw);
79
+ const root = await this.findMarkerForNamespace(cwd, namespace);
80
+ return {
81
+ root: root ?? cwd,
82
+ namespace,
83
+ namespaceSource: "config",
84
+ materialized: root !== null,
85
+ };
36
86
  }
37
- return { namespace: normalizeNamespace(DEFAULT_NAMESPACE), source: "default" };
87
+ const namespace = normalizeNamespace(DEFAULT_NAMESPACE);
88
+ const root = await this.findMarkerForNamespace(cwd, namespace);
89
+ return {
90
+ root: root ?? cwd,
91
+ namespace,
92
+ namespaceSource: "default",
93
+ materialized: root !== null,
94
+ };
38
95
  }
39
96
  async detectFromWorkspace(cwd) {
97
+ let dir = cwd;
98
+ while (true) {
99
+ const matches = await this.namespacesAt(dir);
100
+ if (matches.length > 1)
101
+ throw new WorklineDirectoryError(dir, matches);
102
+ const [namespace] = matches;
103
+ if (namespace !== undefined)
104
+ return { root: dir, namespace };
105
+ const parent = dirname(dir);
106
+ if (parent === dir)
107
+ return null;
108
+ dir = parent;
109
+ }
110
+ }
111
+ async findMarkerForNamespace(cwd, namespace) {
112
+ let dir = cwd;
113
+ while (true) {
114
+ if (await this.isCanonicalMarker(join(dir, `.${namespace}`, "sessions")))
115
+ return dir;
116
+ const parent = dirname(dir);
117
+ if (parent === dir)
118
+ return null;
119
+ dir = parent;
120
+ }
121
+ }
122
+ async namespacesAt(dir) {
40
123
  let entries;
41
124
  try {
42
- entries = await this.fs.list(cwd);
125
+ entries = await this.fs.list(dir);
43
126
  }
44
127
  catch {
45
- return null;
128
+ return [];
46
129
  }
47
130
  const matches = [];
48
131
  for (const entry of entries) {
49
- if (entry.type !== "dir")
50
- continue;
51
- if (!entry.name.startsWith("."))
132
+ if (entry.type !== "dir" || !entry.name.startsWith("."))
52
133
  continue;
53
134
  const candidate = entry.name.slice(1);
54
135
  if (!NAMESPACE_REGEX.test(candidate))
55
136
  continue;
56
- const sessionsPath = join(entry.path, "sessions");
57
- if (await this.fs.exists(sessionsPath)) {
137
+ if (await this.isCanonicalMarker(join(entry.path, "sessions"))) {
58
138
  matches.push(candidate);
59
139
  }
60
140
  }
61
- if (matches.length === 1)
62
- return matches[0] ?? null;
63
- return null;
141
+ return matches.sort();
142
+ }
143
+ async isCanonicalMarker(path) {
144
+ try {
145
+ return (await this.fs.stat(path)).type === "dir";
146
+ }
147
+ catch {
148
+ return false;
149
+ }
64
150
  }
65
151
  }
66
152
  //# sourceMappingURL=namespace-resolver.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"namespace-resolver.js","sourceRoot":"","sources":["../../src/runtime/namespace-resolver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"namespace-resolver.js","sourceRoot":"","sources":["../../src/runtime/namespace-resolver.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tacuchi/agent-workflow-cli",
3
- "version": "22.4.2",
3
+ "version": "24.0.0",
4
4
  "description": "Runtime CLI for Workline — the stages + loops + artifacts system for agent work. Bundles the universal `w` skill set under `skills/w/` (slash commands `/w:*`: spec-new/spec-refine, plan-new/plan-exec, quick, persist, workspace-init, export-*); `self install --target <host>` copies SKILL + commands + hooks into the host. Pluggable capability skills resolve through `.workflow/skills.toml`. Namespace auto-detected from any `.<ns>/sessions/` dir in CWD; default `workflow`.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -47,6 +47,8 @@
47
47
  "devDependencies": {
48
48
  "@biomejs/biome": "^1.9.4",
49
49
  "@types/node": "^22.10.5",
50
+ "@types/pg": "^8.23.1",
51
+ "@types/pg-cursor": "^2.7.2",
50
52
  "@types/react": "^18.3.28",
51
53
  "ink-testing-library": "^4.0.0",
52
54
  "typescript": "^5.7.3",
@@ -59,6 +61,8 @@
59
61
  "@inkjs/ui": "^2.0.0",
60
62
  "@inquirer/prompts": "^7.10.1",
61
63
  "ink": "^5.2.1",
64
+ "pg": "^8.23.0",
65
+ "pg-cursor": "^2.22.0",
62
66
  "react": "^18.3.1",
63
67
  "smol-toml": "^1.6.1"
64
68
  }
@@ -21,6 +21,6 @@ It implements the **stages + loops + artifacts** model. The design source lives
21
21
  | [`hooks/`](hooks/) | — | Host hook template (branch-check, sql-mutation-guard, checkpoint, …) |
22
22
  | [`SKILL.md`](SKILL.md) | overview | The `w` orientation skill (guide to the full model) |
23
23
 
24
- ## Bootstrap
24
+ ## Workspace
25
25
 
26
- Run [`/w:workspace-init`](commands/workspace-init.md) once to turn a folder into a workspace (minimal scaffold: `.workflow/sessions/` + `.workflow/skills.toml` + `WORKSPACE` block + CLI-owned `.gitignore`; `docs/` folders are born on demand). No project/hub distinction — a workspace has 1+ sources.
26
+ Every invoked directory is a usable implicit workspace. The closest `.<namespace>/sessions/` ancestor supplies its root; with none, the invoked directory itself is the root. [`/w:workspace-init`](commands/workspace-init.md) is optional: it materializes the small runtime early, or configures explicit sources and overrides.
package/skills/w/SKILL.md CHANGED
@@ -27,9 +27,9 @@ Anyone needing orientation — a loop at start, a new agent in the workspace, or
27
27
 
28
28
  ## Knowledge
29
29
 
30
- ### Workspace (no modes)
30
+ ### Workspace (implicit first)
31
31
 
32
- A single concept: **workspace**. There is no project/hub split. The folder where the agent starts becomes a workspace with `/w:workspace-init` (minimal scaffold: `.workflow/sessions/` + `.workflow/skills.toml` + the `WORKSPACE` block in CLAUDE.md + the CLI-owned `.gitignore`; each `docs/<cat>` folder is born on demand at `aw next-number`). It has 1+ sources (repos); "standalone" = a single source.
32
+ A single concept: **workspace**. There is no project/hub split and no mandatory initialization. The nearest ancestor containing `.<namespace>/sessions/` is the root; with no marker, the folder where the agent starts is the **implicit workspace** root. A pure read never creates the marker. The first mutation materializes only the runtime and `/w:workspace-init` is an optional early materialization; explicit sources add configured metadata. `workspace` is the reserved source that points to the root, and any extra alias is explicit.
33
33
 
34
34
  ### The 3-layer architecture + `docs/` zone
35
35
 
@@ -77,14 +77,13 @@ Both authoring entry points can **split** with consent: `spec-new` may split a m
77
77
 
78
78
  ### Operating context — where everything lands
79
79
 
80
- Before any loop, the AI resolves its **operating context** on **every prompt** with two detections: **workspace?** (`.<ns>/sessions/` exists) + **session to continue?** (an active one, or a recent one this prompt continues). That decides the behavior and **where artifacts land** (SQL, scripts, decisions, …):
80
+ Before any loop, the AI resolves the **workspace root** on every prompt (closest `.<ns>/sessions/` ancestor, otherwise the invoked directory) and then the session to continue. The marker is evidence of materialization, not permission to use Workline; pure reads stay byte-identical. That decides where artifacts land:
81
81
 
82
- | Workspace? | Trigger | → Behavior + routing |
83
- |---|---|---|
84
- | **Yes** | **flow command** (`quick`·`spec-*`·`plan-*`) | **new work line** → creates a **new** session (except re-running the same flow over the same input: `create_or_resume` reopens the existing one), starts the loop → artifacts go to **that** session (`SCRIPTS.sql`, …) |
85
- | **Yes** | **prompt with no command** (related) | **continues/reopens the most recent session** → scripts edit **its** `SCRIPTS.sql` (no new session) |
86
- | **Yes** | **prompt with no command** (unrelated / no session) | **no flow**: direct work → writes into `docs/` by convention + numbering (`aw next-number`). To persist work already done in this conversation, `/w:persist` classifies and routes it (`docs/research` · spec draft · plan adoption) |
87
- | **No** | anything | **vanilla** — no workspace, no flow; the AI is free (native) |
82
+ | Trigger | → Behavior + routing |
83
+ |---|---|
84
+ | **flow command** (`quick`·`spec-*`·`plan-*`) | **new work line** → materializes if needed, creates a **new** session (except re-running the same flow over the same input: `create_or_resume` reopens the existing one), starts the loop → artifacts go to **that** session (`SCRIPTS.sql`, …) |
85
+ | **prompt with no command** (related) | **continues/reopens the most recent session** → scripts edit its `SCRIPTS.sql` (no new session) |
86
+ | **prompt with no command** (unrelated / no session) | **no flow**: direct work → writes into `docs/` by convention + numbering (`aw next-number`). To persist work already done in this conversation, `/w:persist` classifies and routes it (`docs/research` · spec draft · plan adoption) |
88
87
 
89
88
  **Continuity rule** (single source — the chassis and the loops reference here):
90
89
 
@@ -103,7 +102,7 @@ The flows are **composable with host-native work, never exclusive**. The host is
103
102
 
104
103
  ### The commands (`/w:` namespace)
105
104
 
106
- - `/w:workspace-init` — initializes the workspace.
105
+ - `/w:workspace-init` — materializes the runtime early, or configures explicit sources.
107
106
  - `/w:spec-new` — generates an initial spec (single-pass, no loop; a bounded reconnaissance of the sources precedes the scope decision).
108
107
  - `/w:spec-refine` — starts `spec-refine-loop` to refine the spec until it is `ready-for-plan`: the blocking functional decisions closed, the architecture/implementation ones declared for PLAN.
109
108
  - `/w:plan-new` — starts `plan-new-loop` to derive an executable plan from the ready spec.
@@ -19,7 +19,7 @@ Central distinction of the model:
19
19
 
20
20
  > An artifact may be **promoted** to a `docs/` document (e.g. `SCRIPTS.sql` → `docs/scripts/`) — but **only via dedicated `export-*` skills**, **never** automatically by the loops. The spec and the plan **are not** artifacts: they are documents.
21
21
 
22
- > **Routing by operating context** (canonical rules: [`../SKILL.md`](../SKILL.md) § *Operating context*): inside a flow → the **active/continued** session (a prompt with no command edits the most recent session's artifacts); workspace without flow → `docs/` by convention + numbering (or explicitly via [`/w:persist`](../commands/persist.md), which classifies in-conversation work and routes it — `docs/research` · spec draft · plan adoption); no workspace → vanilla. Session→`docs/` promotion is still **only** via `export-*`; persist is the **host→`docs/`** path (it never reads sessions).
22
+ > **Routing by operating context** (canonical rules: [`../SKILL.md`](../SKILL.md) § *Operating context*): inside a flow → the **active/continued** session (a prompt with no command edits the most recent session's artifacts); without a flow → `docs/` by convention + numbering (or explicitly via [`/w:persist`](../commands/persist.md), which classifies in-conversation work and routes it — `docs/research` · spec draft · plan adoption). Every invoked directory is an implicit root and reads create no marker. Session→`docs/` promotion is still **only** via `export-*`; persist is the **host→`docs/`** path (it never reads sessions).
23
23
 
24
24
  ---
25
25
 
@@ -6,15 +6,15 @@
6
6
 
7
7
  ---
8
8
 
9
- ## Bootstrap
9
+ ## Workspace
10
10
 
11
- [`/w:workspace-init`](workspace-init.md) turns the current folder into a **workspace** (minimal scaffold: `.workflow/sessions/` + `.workflow/skills.toml` + `WORKSPACE` block + CLI-owned `.gitignore`; `docs/` folders are born on demand). No project/hub distinction; run once before any flow.
11
+ Every invoked directory is a usable implicit workspace. The closest ancestor with `.<namespace>/sessions/` is reused; otherwise the invoked directory is the root. [`/w:workspace-init`](workspace-init.md) is optional: without sources it materializes only the runtime, and with sources it configures metadata.
12
12
 
13
13
  ## Index
14
14
 
15
15
  | Command | What it does | Mode |
16
16
  |---|---|---|
17
- | [`workspace-init`](workspace-init.md) | Workspace bootstrap | single-pass, interactive |
17
+ | [`workspace-init`](workspace-init.md) | Materialize runtime or configure explicit sources | single-pass, interactive |
18
18
  | [`spec-new`](spec-new.md) | Generates the spec draft (`docs/specs/NNN-spec-<slug>.md`) | single-pass, no loop |
19
19
  | [`spec-refine`](spec-refine.md) | Refines the spec **in place** until it is `ready-for-plan` | starts `spec-refine-loop` |
20
20
  | [`plan-new`](plan-new.md) | Derives the executable plan (`docs/plans/PPP-plan-<slug>.md`) from the spec | starts `plan-new-loop` |
@@ -38,7 +38,9 @@ Captures **work already produced in this conversation** — with or without host
38
38
 
39
39
  Every rejection names its cause and one valid next action; nothing was written. Fix the answer and repeat from step 3.
40
40
 
41
- Requires a **workspace** (`docs/` is the managed surface). Without one → degrade: propose `/w:workspace-init`.
41
+ The resolved **implicit workspace** is the managed surface (`docs/`). No prior
42
+ `/w:workspace-init` is needed: an approved apply writes only its declared
43
+ artifact and materializes the runtime as part of that first mutation.
42
44
 
43
45
  ## More context
44
46
 
@@ -28,7 +28,7 @@ No target → **every** pending item as `candidates` in the CLI's order, `propos
28
28
  2. **One option per candidate** — only for CLI candidates, in its order — each with its re-entry command, plus the `flow` slot. Canonical [option shape](../loops/CHASSIS.md#structured-choice-design--batching) and [host binding](../harness/HARNESS.md#harness-binding-matrix): the title is the label, `Progreso` + `Siguiente` the sentence.
29
29
  3. **Past the host's ceiling**, group by class into ≤3 questions; if a class still will not fit, present them **all** as labelled markdown and declare the degradation. Nothing trimmed, merged or dropped.
30
30
  4. **Choosing invokes that command in the same turn.** The destination flow opens its own session and consent boundaries.
31
- 5. **No candidates** → nothing is pending: say it and stop, opening no choice; cheap host-memory may add a recent-focus note, never expensive or blocking. No workspace → offer `/w:workspace-init`.
31
+ 5. **No candidates** → nothing is pending: say it and stop, opening no choice; cheap host-memory may add a recent-focus note, never expensive or blocking. An implicit workspace returns `idle` without creating files.
32
32
 
33
33
  ## What the CLI decides (do not re-derive)
34
34
 
@@ -25,8 +25,8 @@ Generates `docs/specs/NNN-spec-<slug>.md` in a single pass from the prompt in `$
25
25
 
26
26
  1. **Reconnaissance** — one shallow look at the terrain before any scope decision: adopt what the conversation settled, identify the candidate sources (`aw sources --no-git`, or the `WORKSPACE` block), look at their surface, stop. **Budget: ≤5 reads + ≤3 searches** — a cap, never a target. Never run code, query a database or search the web. Full rules: module `RECONNAISSANCE`.
27
27
  2. **Split gate** — before writing anything, judge whether the prompt bundles several **independent functional outcomes**. Borderline or thin evidence → **one spec, no question** (hypothesis to `## Assumptions`, doubt to `## Open questions`). Only clear signals earn the command's single structured-choice offer. Full rules: module `SPLIT-GATE`.
28
- 3. **Number and slug** — `aw next-number docs/specs --claim spec-<slug>.md` CLAIMS the number and returns `claimed_path`. Derive `<slug>` from the Requirement: short kebab-case, only `[a-z0-9-]`, ≤ ~5 words / ≤ 40 chars.
29
- 4. **Write** `docs/specs/NNN-spec-<slug>.md`, framing `$ARGUMENTS` into the draft schema below; reconnaissance findings land **only** where the filling notes allow. On an accepted split: repeat 3-4 per part, minting immediately before each write.
28
+ 3. **Slug and draft** — derive `<slug>` from the Requirement: short kebab-case, only `[a-z0-9-]`, ≤ ~5 words / ≤ 40 chars. Then frame `$ARGUMENTS` into the draft schema below; reconnaissance findings land **only** where the filling notes allow.
29
+ 4. **Publish it in one act** — `aw next-number docs/specs --publish spec-<slug>.md` with the finished draft on stdin: it assigns the correlative and writes the document atomically, and returns `published_path`. This command has no session, so it never leaves a reservation of nobody's — and an interruption leaves neither file nor consumed number. On an accepted split: repeat 3-4 per part.
30
30
  5. **Report** the generated file(s) and the next step (`/w:spec-refine docs/specs/NNN-spec-<slug>.md`).
31
31
 
32
32
  Steps 1-2 run **only on a raw user prompt** (direct invocation, or the `plan-new` mode-3 handoff). The reuse entries at the end skip them: their context arrives already established, and adopting it is transcription, not investigation.
@@ -26,7 +26,7 @@ Read-only single pass: no loop, no session, no writes. Transversal.
26
26
 
27
27
  > **Automation reads JSON.** Piped or with `--json` / `--format json` it emits its envelope; `--detail` is human-only.
28
28
 
29
- Nothing pending → one line, no empty section. No workspace → it offers `/w:workspace-init`; an empty pipeline for want of one is never "nothing pending".
29
+ Nothing pending → one line, no empty section. In an implicit workspace that is genuinely "nothing pending"; this read creates no marker or other file.
30
30
 
31
31
  ## More context
32
32
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "Use when starting Workline in a folder with no workspace yet — turns it into one (minimal scaffold: sessions marker, skills.toml, WORKSPACE block, .gitignore). Run once before any flow. Backed by `aw workspace-init`."
2
+ description: "Use to materialize Workline runtime early, or configure explicit workspace sources. Flows work without a prior init. Backed by `aw workspace-init`."
3
3
  argument-hint: --source alias:path[:branch] [--proyecto <name>] [--main-branch <branch>] [--dry-run]
4
4
  allowed-tools:
5
5
  [
@@ -8,22 +8,21 @@ allowed-tools:
8
8
  ]
9
9
  ---
10
10
 
11
- # workspace-init — workspace bootstrap
11
+ # workspace-init — materialize or configure
12
12
 
13
- Turns the current folder into a Workline workspace: **1+ sources** (repos), one source = standalone. No project/hub modes.
13
+ Workline already has an implicit workspace at the resolved root: the nearest ancestor with `.<namespace>/sessions/`, or exactly the invoked directory when none exists. It never guesses a Git root.
14
14
 
15
- `aw workspace-init --source alias:path[:branch] [flags above] --format human`
15
+ `aw workspace-init [--source alias:path[:branch]] [flags above] --format human`
16
16
 
17
17
  > **The CLI writes; this wrapper does not** — `Write` and `Edit` are absent from `allowed-tools` on purpose. `--dry-run` previews; re-run without it. Relay the output, never re-render it.
18
18
 
19
- ## Interactive steps
19
+ ## Modes
20
20
 
21
- 1. **Sources** — the CLI detects the repo path(s); the user confirms aliases, paths and branches. Multiple `--source` accepted.
22
- 2. **Default skills** — present the catalog of capabilities (roles). Per role: `built-in default`, a third-party skill (`skills.sh`), or `off`; the result lands in `.workflow/skills.toml`. Cascade: `built-in → ~/.workflow/skills.toml (global) → .workflow/skills.toml (workspace)`. The template also ships a commented `[compaction]` section: the `mode` switch for the loops' context self-regulation (`confirm` default, `auto` opt-in).
23
- 3. **Minimal scaffold** — only the activation set: `.workflow/sessions/` (the marker that activates the operating context), `.workflow/skills.toml`, the `WORKSPACE` block in CLAUDE.md/AGENTS.md and the CLI-owned `.gitignore`. **Nothing else upfront**: each `docs/<category>` is born on demand at its first numbered write (`aw next-number docs/<cat>`), and `.workflow/launch/<alias>/` plus `docs/logs/` at the first launch.
24
- 4. **External sources** — one outside the workspace folder gets multi-root visibility (gitignored) and a reconcile.
21
+ Without sources, it only materializes the minimal runtime under the lock: the CLI-owned `.gitignore` block when the root belongs to Git, then `.<namespace>/sessions/` as the final marker. It does not create `docs/`, `skills.toml`, a WORKSPACE block, launch files, `HISTORY.md` or a Git repository.
25
22
 
26
- **Idempotent** — a re-run reconciles: it keeps manual configuration and prunes the legacy scaffold.
23
+ With `--source`, it configures/reconciles the metadata, branches and multiroot visibility. `workspace` is the reserved implicit source pointing at the root and cannot be configured as an alias. A workspace `skills.toml` is created only when there is a real capability override.
24
+
25
+ Both modes are idempotent. A normal first mutation also materializes the same runtime automatically, so this command is optional rather than a gate.
27
26
 
28
27
  Done → the user can run `/w:spec-new`, `/w:plan-new` or `/w:quick`.
29
28
 
@@ -18,7 +18,7 @@
18
18
  "web": "the run needs evidence from outside the workspace",
19
19
  "reconnaissance": "a draft is being cut from a raw prompt over unfamiliar terrain",
20
20
  "detection": "the CLI's automatic detection was wrong or ambiguous",
21
- "scaffold": "the target folder already carries a workspace",
21
+ "scaffold": "the target has materialized runtime or needs its materialization/configuration contract",
22
22
  "classification": "in-conversation work has to be classified before it is written",
23
23
  "authoring": "the deliverable's own notation, structure or ordering is not obvious from the material"
24
24
  },
@@ -61,9 +61,6 @@
61
61
  "plan.escalation-adopted": "this refine consumed the escalation package an execution handed over, instead of re-deriving its diagnosis",
62
62
  "plan.escalation-absent": "no escalation package reached this refine, so it starts from the document alone",
63
63
  "chassis.context-pressure": "a fresh reader would need the CHECKPOINT to continue this run",
64
- "plan.tasks-to-mark": "at least one task of the batch finished its local work and its checkbox is still open",
65
- "plan.plan-closable": "every phase of the plan will be validated once this batch closes, so the plan can be sealed done",
66
- "plan.commit-pending": "at least one affected source carries uncommitted changes from this batch",
67
64
  "quick.db-touched": "the task read from or wrote to a database, so there is a statement to derive into the session script"
68
65
  },
69
66
  "commands": {
@@ -34,7 +34,7 @@ The capabilities the harness layer depends on, with their universal fallback (wh
34
34
  |---|---|---|
35
35
  | **command-invocation** | the user triggers a flow by name (`spec-new`, `plan-exec`, …) | the user writes "run the `<cmd>` procedure" and the AI reads its doc |
36
36
  | **procedure-loading** | load a loop's/command's doctrine | the AI **reads the `.md`** of the loop and follows it (read-and-follow) |
37
- | **structured-choice** | ask the human ≤3 content questions **+ always** a `flow` control (`Compactar`/`Cerrar`); every option has a semantic label + one-sentence functional explanation/example | **labeled markdown** in chat; answer by label or ratify all first options with `Aceptar recomendaciones` |
37
+ | **structured-choice** | ask the human ≤3 content questions **+ always** a `flow` control (`Compactar`/`Cerrar`); every option has a semantic label + one-sentence functional explanation/example | the host's own tool when the turn offers it; else the **`structured_choice`** tool of Workline's own MCP server, which renders the host's native selector by elicitation (only where the catalog declares it with dated evidence); else **labeled markdown** in chat, answered by label or by ratifying all first options with `Aceptar recomendaciones` |
38
38
  | **compaction** | shrink the context without losing the thread (+ a context-pressure **signal** for the chassis' self-regulation) | write `CHECKPOINT` and ask the user to restart the context and resume (resume keys off `CHECKPOINT`) |
39
39
  | **subagent-dispatch** | *(optional)* parallelize research breadth | **inline sequential** research in the same session (the default anyway) |
40
40
  | **persistent-context** | the `WORKSPACE` block + conventions always present | the repo's context file (standard **`AGENTS.md`**; `CLAUDE.md` on Claude Code) |
@@ -58,7 +58,7 @@ Read **[`../CHASSIS.md`](../CHASSIS.md)** — the loop's **full engine** — **a
58
58
  - **`Recortar alcance`**, if chosen: propose the **sub-task that DOES fit** a quick (`SESSION.Objective` = the sub-task; the original prompt goes into `## Origin`) and defer the rest to `BACKLOG` ("trimmed at the gate — may warrant its own spec, `/w:spec-new`").
59
59
  - **`Cambiar a SPEC`**, if chosen: **no quick session is created** — run the *Live transition to SPEC* (next bullet).
60
60
  - **Live transition to SPEC** (shared by the gate and mid-loop escalation). On acceptance, the work line **moves to the SPEC flow**: the explicit consent in the structured-choice **equals invoking the destination command** (*consented exception* — rule 3 of the *Continuity rule*, [`../../SKILL.md`](../../SKILL.md) § *Operating context*). On the SPEC side:
61
- 1. **Materialize the draft** via the [`../../commands/spec-new.md`](../../commands/spec-new.md) procedure: `aw next-number docs/specs --claim spec-<slug>.md`, schema, single-pass **NO RESEARCH** — its bounded reconnaissance does **not** re-fire (this run's context arrives adopted). `## Origin` = "escalated from `/w:quick`" + the original prompt (+ the origin quick session if it exists). The draft is born `status: draft`: only the SPEC gate promotes it to `ready-for-plan`.
61
+ 1. **Materialize the draft** via the [`../../commands/spec-new.md`](../../commands/spec-new.md) procedure: `aw next-number docs/specs --publish spec-<slug>.md` with the finished draft on stdin (number assigned and document written in one atomic act, no reservation left), schema, single-pass **NO RESEARCH** — its bounded reconnaissance does **not** re-fire (this run's context arrives adopted). `## Origin` = "escalated from `/w:quick`" + the original prompt (+ the origin quick session if it exists). The draft is born `status: draft`: only the SPEC gate promotes it to `ready-for-plan`.
62
62
  2. **Load and execute** [`../spec-refine-loop/LOOP.md`](../spec-refine-loop/LOOP.md) — over that spec (trampoline pattern).
63
63
  3. The run's session is that loop's **normal** `NNN-<slug>-spec-refine` (the CLI numbers it; its `## Origin` records the escalation). **Invariant 2 intact**: quick, while it is quick, never writes `docs/` — the draft is written by the SPEC flow, post-consent.
64
64
  - **Mid-loop escalation + handoff**: if the task grows, declare the signals again — the CLI applies the same threshold and, if it fires, asks. If the user accepts moving up:
@@ -12,4 +12,4 @@ Loaded when a bare prompt continues an existing work line (signal `resume`).
12
12
 
13
13
  > **Which line a prompt joins is not this document's call:** a command opens a new one through `aw session-create`, a bare prompt continues the most recent through `aw resume`. Both fire **before** a run exists, so no journey has a step for them. The reason stays: the **command** is the signal for "new work line", so nobody loses a thread by not typing one, or forks one by typing it twice.
14
14
 
15
- Whether a prompt really belongs to the open line is judgment. Clearly unrelated → offer choosing (`continuar NNN` | `trabajo nuevo`) or fall to the **no-flow** branch (`docs/` by convention + numbering). No workspace → **vanilla** behavior.
15
+ Whether a prompt really belongs to the open line is judgment. Clearly unrelated → offer choosing (`continuar NNN` | `trabajo nuevo`) or fall to the **no-flow** branch (`docs/` by convention + numbering). Every invoked directory has an implicit Workline root; a marker is created only by a mutation.
@@ -1,28 +1,25 @@
1
- # WORKSPACE-SCAFFOLD — what init versions, ignores and prunes
1
+ # WORKSPACE-SCAFFOLD — runtime materialization and configuration
2
2
 
3
- Loaded when the folder already has a workspace, or the user asks what `workspace-init` writes,
4
- ignores or removes on a re-run (signal `scaffold`).
3
+ Loaded when the folder already has a materialized workspace, or the user asks what
4
+ `workspace-init` writes, ignores or reconciles on a re-run (signal `scaffold`).
5
5
 
6
6
  ## Versioning policy (CLI-owned `.gitignore`)
7
7
 
8
- Init writes and owns the full set.
8
+ The first mutation (or `workspace-init` without sources) writes only the runtime set, under the
9
+ workspace lock. The sessions marker is created last.
9
10
 
10
- - **Ignored** — `.workflow/sessions/` (machine-local live log), `.workflow/.lock`,
11
- `.workflow/processes.json`, `.workflow/launch/`, `docs/logs/` and, when there are external
12
- sources, `.claude/settings.local.json*` / `.codex/config.toml*` (the patterns cover the
13
- `.bak.<epoch>` backups).
14
- - **Versioned** — `.workflow/skills.toml`, `docs/**` (the deliverables) and
15
- `.workflow/HISTORY.md`, the durable record: `aw session-close` upserts each closed session's
16
- row there.
11
+ - **Ignored** — `.<namespace>/sessions/` (machine-local live log), `.<namespace>/.lock`,
12
+ `.<namespace>/processes.json`, `.<namespace>/launch/` and `docs/logs/`. The runtime block is
13
+ added only when the root belongs to Git.
14
+ - **Not created by materialization** — `docs/**`, `skills.toml`, a WORKSPACE block, launch
15
+ files, HISTORY and Git metadata. Those belong to their owning command.
17
16
 
18
- ## Re-run: reconcile + prune
17
+ ## Re-run: reconcile
19
18
 
20
- A re-run adds no duplicate entries and overwrites no manual configuration. It prunes the legacy
21
- upfront scaffold:
19
+ A re-run adds no duplicate runtime entries and overwrites no manual configuration. When explicit
20
+ sources are supplied, it reconciles their metadata, branches and multiroot visibility; a
21
+ `workspace` alias is reserved for the implicit root. It creates `skills.toml` only for a real
22
+ override.
22
23
 
23
- - `.gitkeep`-only taxonomy folders and stray `.gitkeep` files;
24
- - an empty `docs/logs/`;
25
- - a released `.workflow/.lock` leftover.
26
-
27
- The `.gitignore` is completed to the current set — entries merge under the existing header, never
28
- duplicated.
24
+ The `.gitignore` runtime block merges idempotently; a read such as `status` or `resume` never
25
+ creates it or any other workspace file.
@@ -78,7 +78,7 @@
78
78
  "items": { "enum": ["direct", "compose"] }
79
79
  },
80
80
  "workspace": {
81
- "description": "Whether the operation needs a Workline workspace. Being outside one returns an explicit result and never initializes Workline implicitly.",
81
+ "description": "Whether the operation needs a resolved Workline root. The CLI treats the invoked directory as an implicit root; a caller without one receives an explicit result and never materializes Workline by reading.",
82
82
  "enum": ["required", "optional", "standalone"]
83
83
  },
84
84
  "interaction": {