@tacuchi/agent-workflow-cli 22.1.0 → 22.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/application/resume-service.js +45 -114
- package/dist/application/resume-service.js.map +1 -1
- package/dist/application/self/codex-plugin.js +87 -0
- package/dist/application/self/codex-plugin.js.map +1 -0
- package/dist/application/self/hooks-dialect.js +18 -0
- package/dist/application/self/hooks-dialect.js.map +1 -0
- package/dist/application/self/hooks-json.js +226 -0
- package/dist/application/self/hooks-json.js.map +1 -0
- package/dist/application/self/hooks-toml.js +4 -11
- package/dist/application/self/hooks-toml.js.map +1 -1
- package/dist/application/self/host-states.js +64 -3
- package/dist/application/self/host-states.js.map +1 -1
- package/dist/application/self/install-hooks.js +291 -37
- package/dist/application/self/install-hooks.js.map +1 -1
- package/dist/application/self/install-skill.js +7 -2
- package/dist/application/self/install-skill.js.map +1 -1
- package/dist/application/self/opencode-plugin.js +167 -0
- package/dist/application/self/opencode-plugin.js.map +1 -0
- package/dist/application/self/uninstall.js +147 -1
- package/dist/application/self/uninstall.js.map +1 -1
- package/dist/application/status-service.js +1 -0
- package/dist/application/status-service.js.map +1 -1
- package/dist/application/workline-index-service.js +143 -28
- package/dist/application/workline-index-service.js.map +1 -1
- package/dist/cli/commands/resume.js +20 -3
- package/dist/cli/commands/resume.js.map +1 -1
- package/dist/cli/commands/status.js +57 -8
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/tui/app.js +1 -1
- package/dist/cli/tui/app.js.map +1 -1
- package/dist/cli/tui/components/host-admin-section.js +53 -21
- package/dist/cli/tui/components/host-admin-section.js.map +1 -1
- package/dist/cli/tui/tabs/mcp-tab.js +20 -5
- package/dist/cli/tui/tabs/mcp-tab.js.map +1 -1
- package/dist/cli/tui/tabs/workflow-tab.js +2 -2
- package/dist/cli/tui/tabs/workflow-tab.js.map +1 -1
- package/dist/domain/harnesses.js +166 -10
- package/dist/domain/harnesses.js.map +1 -1
- package/package.json +1 -1
- package/skills/w/commands/resume.md +19 -12
- package/skills/w/commands/status.md +9 -5
- package/skills/w/commands/workspace-init.md +6 -6
- package/skills/w/harness/HARNESS.md +10 -6
|
@@ -2,7 +2,7 @@ import { coreDocumentLocations } from "../domain/docs-canon.js";
|
|
|
2
2
|
import { projectRun } from "./flow/run-projection.js";
|
|
3
3
|
import { buildSessionNarrative } from "./session-narrative.js";
|
|
4
4
|
import { resolveSessionTarget, sessionReadRequest } from "./session-resolver.js";
|
|
5
|
-
import { buildWorklineIndex, } from "./workline-index-service.js";
|
|
5
|
+
import { buildWorklineIndex, planDetail, specDetail, unresolvedDesignRefs, } from "./workline-index-service.js";
|
|
6
6
|
export async function runResume(fs, env, paths, input = {}) {
|
|
7
7
|
const index = await buildWorklineIndex(fs, env, paths, {
|
|
8
8
|
...(input.now !== undefined ? { now: input.now } : {}),
|
|
@@ -19,7 +19,13 @@ export async function runResume(fs, env, paths, input = {}) {
|
|
|
19
19
|
return await resumeSession(fs, paths, index, input);
|
|
20
20
|
if (input.target !== undefined)
|
|
21
21
|
return resumeTarget(index, input.target);
|
|
22
|
-
|
|
22
|
+
if (!index.workspace.initialized) {
|
|
23
|
+
return {
|
|
24
|
+
status: "uninitialized",
|
|
25
|
+
action: `no hay workspace de Workline en ${index.workspace.path}: creá uno con /w:workspace-init`,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
return resumePipeline(index);
|
|
23
29
|
}
|
|
24
30
|
// ── explicit target ──────────────────────────────────────────────────────────
|
|
25
31
|
/**
|
|
@@ -72,166 +78,91 @@ async function resumeSession(fs, paths, index, input) {
|
|
|
72
78
|
};
|
|
73
79
|
}
|
|
74
80
|
// ── no target: the documental pipeline ───────────────────────────────────────
|
|
75
|
-
|
|
81
|
+
/**
|
|
82
|
+
* The whole pipeline comes back as candidates, in the order the CLI decided.
|
|
83
|
+
*
|
|
84
|
+
* It used to offer only the head and its ties, so the open plans below them were
|
|
85
|
+
* pending work `status` listed and `resume` never named — and choosing what to
|
|
86
|
+
* pick up meant reading one surface and typing from the other. Priority and the
|
|
87
|
+
* tie-break are untouched: what a tie still changes is whether one item can be
|
|
88
|
+
* called the recommendation at all.
|
|
89
|
+
*/
|
|
90
|
+
function resumePipeline(index) {
|
|
76
91
|
const [head] = index.pipeline;
|
|
77
92
|
if (head === undefined) {
|
|
78
93
|
return { status: "idle", action: "no hay trabajo pendiente: el pipeline está vacío" };
|
|
79
94
|
}
|
|
95
|
+
const candidates = index.pipeline.map((item) => pipelineProposal(index, item));
|
|
80
96
|
// A tie is priority + progress, never date. Two items that reach here are
|
|
81
97
|
// equally next, and picking one for the user is what this replaces.
|
|
82
98
|
const tied = index.pipeline.filter((item) => item.priority === head.priority && (item.started ?? false) === (head.started ?? false));
|
|
83
99
|
if (tied.length > 1) {
|
|
84
|
-
const candidates = await Promise.all(tied.map((item) => pipelineProposal(fs, paths, index, item)));
|
|
85
100
|
return {
|
|
86
101
|
status: "candidates",
|
|
87
102
|
candidates,
|
|
88
|
-
action: `${tied.length} candidatos
|
|
103
|
+
action: `${tied.length} candidatos empatados en cabeza sobre ${candidates.length} pendientes: elegí uno y volvé a invocar con su ruta`,
|
|
89
104
|
};
|
|
90
105
|
}
|
|
91
106
|
return {
|
|
92
107
|
status: "proposal",
|
|
93
108
|
via: "pipeline",
|
|
94
|
-
proposal:
|
|
109
|
+
proposal: pipelineProposal(index, head),
|
|
110
|
+
candidates,
|
|
95
111
|
};
|
|
96
112
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
return await sessionProposal(fs, paths, session.folder, session.path, session);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
const spec = index.specs.find((s) => s.file === item.file);
|
|
110
|
-
if (spec !== undefined)
|
|
111
|
-
return specProposal(spec, index);
|
|
113
|
+
/**
|
|
114
|
+
* A pipeline item, projected — never looked up and re-derived.
|
|
115
|
+
*
|
|
116
|
+
* The item already carries what it owes, computed once where the pipeline is
|
|
117
|
+
* built, so this cannot describe the same item differently from the board that
|
|
118
|
+
* lists it. It used to re-find the spec or plan behind the row and run the
|
|
119
|
+
* derivation again, which is exactly the seam the two surfaces drifted through.
|
|
120
|
+
*/
|
|
121
|
+
function pipelineProposal(index, item) {
|
|
112
122
|
return {
|
|
113
123
|
kind: item.kind,
|
|
114
124
|
file: item.file,
|
|
115
125
|
number: item.number,
|
|
116
|
-
|
|
117
|
-
progress: "—",
|
|
118
|
-
next: item.summary,
|
|
126
|
+
...told(item.detail),
|
|
119
127
|
command: item.command,
|
|
128
|
+
...designOf(index, item.file),
|
|
120
129
|
};
|
|
121
130
|
}
|
|
122
131
|
// ── proposals ────────────────────────────────────────────────────────────────
|
|
123
132
|
function specProposal(spec, index) {
|
|
124
|
-
const planned = index.plans.some((p) => p.spec.status === "resolved" && p.spec.number === spec.number);
|
|
125
133
|
const refine = spec.status !== "ready-for-plan";
|
|
126
134
|
return {
|
|
127
135
|
kind: refine ? "spec-unrefined" : "spec-unplanned",
|
|
128
136
|
file: spec.file,
|
|
129
137
|
number: spec.number,
|
|
130
|
-
|
|
131
|
-
progress: `status ${spec.status}, ${spec.open_questions} pregunta(s) abierta(s)`,
|
|
132
|
-
next: refine
|
|
133
|
-
? "refinar hasta ready-for-plan"
|
|
134
|
-
: planned
|
|
135
|
-
? "ya tiene plan derivado"
|
|
136
|
-
: "generar su plan",
|
|
138
|
+
...told(specDetail(spec, index.plans)),
|
|
137
139
|
command: refine ? `/w:spec-refine ${spec.file}` : `/w:plan-new ${spec.file}`,
|
|
138
140
|
...designOf(index, spec.file),
|
|
139
141
|
};
|
|
140
142
|
}
|
|
141
143
|
function planProposal(plan, index) {
|
|
142
|
-
const [blocked] = plan.blocked_phases;
|
|
143
|
-
const phases = plan.phases_total > 0 ? ` · fases ${plan.phases_validated}/${plan.phases_total}` : "";
|
|
144
|
-
const design = designOf(index, plan.file);
|
|
145
144
|
return {
|
|
146
145
|
kind: "plan-open",
|
|
147
146
|
file: plan.file,
|
|
148
147
|
number: plan.number,
|
|
149
|
-
|
|
150
|
-
progress: `${plan.tasks_done}/${plan.tasks_total} tareas (${plan.progress_pct}%)${phases}`,
|
|
151
|
-
// A missing reference outranks the plan's own next step: plan-exec fails
|
|
152
|
-
// closed on it, so proposing "implementá F3" would send someone into a wall.
|
|
153
|
-
next: describeMissingDesign(design) ?? describePlanNext(plan, blocked),
|
|
148
|
+
...told(planDetail(plan, index.designs)),
|
|
154
149
|
command: `/w:plan-exec ${plan.file}`,
|
|
155
|
-
...
|
|
150
|
+
...designOf(index, plan.file),
|
|
156
151
|
};
|
|
157
152
|
}
|
|
153
|
+
/** The three fields a proposal takes verbatim from the shared derivation. */
|
|
154
|
+
function told(detail) {
|
|
155
|
+
return { objective: detail.objective, progress: detail.progress, next: detail.next };
|
|
156
|
+
}
|
|
158
157
|
/** The document's non-valid references, or nothing at all to say. */
|
|
159
158
|
function designOf(index, file) {
|
|
160
|
-
const design = index.designs.
|
|
161
|
-
|
|
162
|
-
|
|
159
|
+
const design = unresolvedDesignRefs(index.designs, file).map((r) => ({
|
|
160
|
+
state: r.state,
|
|
161
|
+
baseline: r.baseline,
|
|
162
|
+
detail: r.detail,
|
|
163
|
+
}));
|
|
163
164
|
return design.length === 0 ? {} : { design };
|
|
164
165
|
}
|
|
165
|
-
function describeMissingDesign(design) {
|
|
166
|
-
const missing = (design.design ?? []).filter((d) => d.state === "missing");
|
|
167
|
-
const [first] = missing;
|
|
168
|
-
if (first === undefined)
|
|
169
|
-
return null;
|
|
170
|
-
return `DISEÑO IRRESOLUBLE ${first.baseline} — ${first.detail ?? "no resuelve"}`;
|
|
171
|
-
}
|
|
172
|
-
function describePlanNext(plan, blocked) {
|
|
173
|
-
if (blocked !== undefined) {
|
|
174
|
-
return `BLOQUEADA F${blocked.number} — ${blocked.blocker ?? "sin motivo declarado"}`;
|
|
175
|
-
}
|
|
176
|
-
// Compensation outranks every reading below it, and it outranks the
|
|
177
|
-
// `inconsistent` line too: a plan held open by an obligation has counters that
|
|
178
|
-
// agree perfectly, so "sus contadores no lo respaldan" would send somebody to
|
|
179
|
-
// repair a document that is not broken. What is owed is work, not a fix.
|
|
180
|
-
const owed = describePendingReconciliation(plan);
|
|
181
|
-
if (owed !== null)
|
|
182
|
-
return owed;
|
|
183
|
-
if (plan.plan_state === "inconsistent") {
|
|
184
|
-
return "el plan se declara done pero sus contadores no lo respaldan: repararlo a mano";
|
|
185
|
-
}
|
|
186
|
-
// Said before the phase counters, because "continuar por la primera fase no
|
|
187
|
-
// validada" is advice about a contract we cannot prove this plan is on.
|
|
188
|
-
if (plan.baseline.status !== "aligned")
|
|
189
|
-
return describeUnprovenBaseline(plan);
|
|
190
|
-
if (plan.final_validation_pending)
|
|
191
|
-
return "todo ejecutado: falta la validación final y el cierre";
|
|
192
|
-
return "continuar por la primera fase no validada";
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* What a plan owes, when it owes anything — the one thing that must be said
|
|
196
|
-
* before offering to run or to close it.
|
|
197
|
-
*
|
|
198
|
-
* Both halves of AC-11 come from here: a plan with an open obligation is neither
|
|
199
|
-
* executable as it stands nor closable, and saying so with the obligation and
|
|
200
|
-
* its resume point is what keeps the refusal actionable instead of a wall.
|
|
201
|
-
*/
|
|
202
|
-
function describePendingReconciliation(plan) {
|
|
203
|
-
const reconciliation = plan.reconciliation;
|
|
204
|
-
if (reconciliation === null || reconciliation.closable)
|
|
205
|
-
return null;
|
|
206
|
-
const [first] = reconciliation.pending;
|
|
207
|
-
if (first === undefined) {
|
|
208
|
-
return "RECONCILIACIÓN PENDIENTE — el contrato efectivo no se puede componer: ni ejecutable ni cerrable";
|
|
209
|
-
}
|
|
210
|
-
const more = reconciliation.pending.length - 1;
|
|
211
|
-
const rest = more > 0 ? ` (+${more} más)` : "";
|
|
212
|
-
return `RECONCILIACIÓN PENDIENTE por ${first.by} — ${first.text}${rest}: retomá en ${first.resume_point}, ni ejecutable ni cerrable tal cual`;
|
|
213
|
-
}
|
|
214
|
-
/**
|
|
215
|
-
* A plan whose baseline nobody can prove, said as exactly that.
|
|
216
|
-
*
|
|
217
|
-
* The 31 plans that predate the seal are the common case, and the honest report
|
|
218
|
-
* is "it does not have one" — never "aligned" and never "derived from the
|
|
219
|
-
* current contract". A divergent seal is the louder version of the same problem
|
|
220
|
-
* and gets its own line rather than being folded in.
|
|
221
|
-
*/
|
|
222
|
-
function describeUnprovenBaseline(plan) {
|
|
223
|
-
const baseline = plan.baseline;
|
|
224
|
-
if (baseline.status === "divergent") {
|
|
225
|
-
return `BASELINE DIVERGENTE — la spec cambió desde que se selló (${baseline.sealed_digest} → ${baseline.current_digest}): revisá el plan contra la spec vigente antes de seguir`;
|
|
226
|
-
}
|
|
227
|
-
if (baseline.status === "malformed") {
|
|
228
|
-
return `BASELINE ILEGIBLE — ${baseline.why}: ${baseline.action}`;
|
|
229
|
-
}
|
|
230
|
-
if (baseline.status === "unresolved") {
|
|
231
|
-
return `BASELINE SIN SPEC — ${baseline.path} no está en el workspace: no hay contrato contra el que validar`;
|
|
232
|
-
}
|
|
233
|
-
return "SIN SELLO DE BASELINE — el plan no dice de qué versión de su spec deriva: no se puede afirmar que esté alineado";
|
|
234
|
-
}
|
|
235
166
|
/**
|
|
236
167
|
* A session's proposal, answered from the session's own narrative.
|
|
237
168
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resume-service.js","sourceRoot":"","sources":["../../src/application/resume-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAMhE,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AACjF,OAAO,EAOL,kBAAkB,GACnB,MAAM,6BAA6B,CAAC;AAiErC,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,EAAkB,EAClB,GAAY,EACZ,KAAmB,EACnB,QAAqB,EAAE;IAEvB,MAAM,KAAK,GAAG,MAAM,kBAAkB,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE;QACrD,GAAG,CAAC,KAAK,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtD,GAAG,CAAC,KAAK,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACvD,CAAC,CAAC;IAEH,IAAI,KAAK,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;QACzC,OAAO;YACL,MAAM,EAAE,gBAAgB;YACxB,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,IAAI,EAAE;YACxC,MAAM,EAAE,qCAAqC,KAAK,CAAC,gBAAgB,uCAAuC;SAC3G,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,MAAM,aAAa,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAClF,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACzE,OAAO,MAAM,cAAc,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AAChD,CAAC;AAED,gFAAgF;AAEhF;;;;;;GAMG;AACH,SAAS,YAAY,CAAC,KAAoB,EAAE,MAAc;IACxD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;IAClF,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;IAElF,MAAM,OAAO,GAAqB;QAChC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QAC3C,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;KAClD,CAAC;IAEF,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC;IACxB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO;YACL,MAAM,EAAE,gBAAgB;YACxB,MAAM;YACN,MAAM,EAAE,kCAAkC,MAAM,yBAAyB,qBAAqB,EAAE,4CAA4C;SAC7I,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO;YACL,MAAM,EAAE,YAAY;YACpB,UAAU,EAAE,OAAO;YACnB,MAAM,EAAE,IAAI,MAAM,gBAAgB,OAAO,CAAC,MAAM,0CAA0C;SAC3F,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AAClE,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,EAAkB,EAClB,KAAmB,EACnB,KAAoB,EACpB,KAAkB;IAElB,MAAM,UAAU,GAAG,MAAM,oBAAoB,CAAC,EAAE,EAAE,KAAK,EAAE,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC;IAEpF,IAAI,UAAU,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;QACtC,OAAO;YACL,MAAM,EAAE,gBAAgB;YACxB,MAAM,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE;YACxB,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC;IACzC,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;IAChE,MAAM,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC;IACtD,OAAO;QACL,MAAM,EAAE,UAAU;QAClB,GAAG,EAAE,UAAU;QACf,QAAQ,EAAE,MAAM,eAAe,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC;KAClE,CAAC;AACJ,CAAC;AAED,gFAAgF;AAEhF,KAAK,UAAU,cAAc,CAC3B,EAAkB,EAClB,KAAmB,EACnB,KAAoB;IAEpB,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC;IAC9B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,kDAAkD,EAAE,CAAC;IACxF,CAAC;IAED,0EAA0E;IAC1E,oEAAoE;IACpE,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAChC,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC,CACzF,CAAC;IAEF,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,CAClC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,gBAAgB,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAC7D,CAAC;QACF,OAAO;YACL,MAAM,EAAE,YAAY;YACpB,UAAU;YACV,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,6EAA6E;SACpG,CAAC;IACJ,CAAC;IACD,OAAO;QACL,MAAM,EAAE,UAAU;QAClB,GAAG,EAAE,UAAU;QACf,QAAQ,EAAE,MAAM,gBAAgB,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC;KACzD,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,gBAAgB,CAC7B,EAAkB,EAClB,KAAmB,EACnB,KAAoB,EACpB,IAAkB;IAElB,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3D,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC3D,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC;QACnE,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,MAAM,eAAe,CAAC,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACjF,CAAC;IACH,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3D,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACzD,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,SAAS,EAAE,IAAI,CAAC,OAAO;QACvB,QAAQ,EAAE,GAAG;QACb,IAAI,EAAE,IAAI,CAAC,OAAO;QAClB,OAAO,EAAE,IAAI,CAAC,OAAO;KACtB,CAAC;AACJ,CAAC;AAED,gFAAgF;AAEhF,SAAS,YAAY,CAAC,IAAiB,EAAE,KAAoB;IAC3D,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAC9B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,UAAU,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,CACrE,CAAC;IACF,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,KAAK,gBAAgB,CAAC;IAChD,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,gBAAgB;QAClD,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,SAAS,EAAE,QAAQ,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;QACrE,QAAQ,EAAE,UAAU,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,cAAc,yBAAyB;QAChF,IAAI,EAAE,MAAM;YACV,CAAC,CAAC,8BAA8B;YAChC,CAAC,CAAC,OAAO;gBACP,CAAC,CAAC,wBAAwB;gBAC1B,CAAC,CAAC,iBAAiB;QACvB,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,kBAAkB,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,eAAe,IAAI,CAAC,IAAI,EAAE;QAC5E,GAAG,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC;KAC9B,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,IAAiB,EAAE,KAAoB;IAC3D,MAAM,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC;IACtC,MAAM,MAAM,GACV,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACxF,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1C,OAAO;QACL,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,SAAS,EAAE,QAAQ,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;QACrE,QAAQ,EAAE,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,WAAW,YAAY,IAAI,CAAC,YAAY,KAAK,MAAM,EAAE;QAC1F,yEAAyE;QACzE,6EAA6E;QAC7E,IAAI,EAAE,qBAAqB,CAAC,MAAM,CAAC,IAAI,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC;QACtE,OAAO,EAAE,gBAAgB,IAAI,CAAC,IAAI,EAAE;QACpC,GAAG,MAAM;KACV,CAAC;AACJ,CAAC;AAED,qEAAqE;AACrE,SAAS,QAAQ,CAAC,KAAoB,EAAE,IAAY;IAClD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU;SACpC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,KAAK,KAAK,OAAO,CAAC;SACrD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC5E,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;AAC/C,CAAC;AAED,SAAS,qBAAqB,CAAC,MAAsC;IACnE,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;IAC3E,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC;IACxB,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACrC,OAAO,sBAAsB,KAAK,CAAC,QAAQ,MAAM,KAAK,CAAC,MAAM,IAAI,aAAa,EAAE,CAAC;AACnF,CAAC;AAED,SAAS,gBAAgB,CACvB,IAAiB,EACjB,OAA0D;IAE1D,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,cAAc,OAAO,CAAC,MAAM,MAAM,OAAO,CAAC,OAAO,IAAI,sBAAsB,EAAE,CAAC;IACvF,CAAC;IACD,oEAAoE;IACpE,+EAA+E;IAC/E,8EAA8E;IAC9E,yEAAyE;IACzE,MAAM,IAAI,GAAG,6BAA6B,CAAC,IAAI,CAAC,CAAC;IACjD,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC/B,IAAI,IAAI,CAAC,UAAU,KAAK,cAAc,EAAE,CAAC;QACvC,OAAO,+EAA+E,CAAC;IACzF,CAAC;IACD,4EAA4E;IAC5E,wEAAwE;IACxE,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,wBAAwB,CAAC,IAAI,CAAC,CAAC;IAC9E,IAAI,IAAI,CAAC,wBAAwB;QAAE,OAAO,uDAAuD,CAAC;IAClG,OAAO,2CAA2C,CAAC;AACrD,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,6BAA6B,CAAC,IAAiB;IACtD,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;IAC3C,IAAI,cAAc,KAAK,IAAI,IAAI,cAAc,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IACpE,MAAM,CAAC,KAAK,CAAC,GAAG,cAAc,CAAC,OAAO,CAAC;IACvC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,iGAAiG,CAAC;IAC3G,CAAC;IACD,MAAM,IAAI,GAAG,cAAc,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/C,OAAO,gCAAgC,KAAK,CAAC,EAAE,MAAM,KAAK,CAAC,IAAI,GAAG,IAAI,eAAe,KAAK,CAAC,YAAY,sCAAsC,CAAC;AAChJ,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,wBAAwB,CAAC,IAAiB;IACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;IAC/B,IAAI,QAAQ,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;QACpC,OAAO,4DAA4D,QAAQ,CAAC,aAAa,MAAM,QAAQ,CAAC,cAAc,0DAA0D,CAAC;IACnL,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;QACpC,OAAO,uBAAuB,QAAQ,CAAC,GAAG,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;IACnE,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;QACrC,OAAO,uBAAuB,QAAQ,CAAC,IAAI,iEAAiE,CAAC;IAC/G,CAAC;IACD,OAAO,iHAAiH,CAAC;AAC3H,CAAC;AAED;;;;;;;;;GASG;AACH,KAAK,UAAU,eAAe,CAC5B,EAAkB,EAClB,KAAmB,EACnB,MAAc,EACd,IAAY,EACZ,OAAmC;IAEnC,MAAM,SAAS,GAAG,MAAM,qBAAqB,CAAC,EAAE,EAAE,KAAK,EAAE;QACvD,MAAM;QACN,IAAI;QACJ,GAAG,CAAC,OAAO,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/D,CAAC,CAAC;IACH,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,CAAC;IAC1D,MAAM,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC,OAAO,CAAC;IACnC,OAAO;QACL,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,MAAM;QACZ,MAAM,EAAE,OAAO,EAAE,IAAI,IAAI,IAAI;QAC7B,SAAS,EAAE,SAAS,CAAC,SAAS,EAAE,IAAI,IAAI,OAAO,EAAE,OAAO,IAAI,MAAM;QAClE,QAAQ,EACN,MAAM,KAAK,SAAS;YAClB,CAAC,CAAC,UAAU,SAAS,CAAC,KAAK,yBAAyB;YACpD,CAAC,CAAC,UAAU,SAAS,CAAC,KAAK,KAAK,MAAM,CAAC,IAAI,EAAE;QACjD,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,IAAI,IAAI,4CAA4C;QAC1E,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,4BAA4B,MAAM,WAAW;QAC/E,GAAG,CAAC,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtF,GAAG,CAAC,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACpE,CAAC;AACJ,CAAC"}
|
|
1
|
+
{"version":3,"file":"resume-service.js","sourceRoot":"","sources":["../../src/application/resume-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// Codex's OTHER hook route: a plugin bundle instead of `~/.codex/hooks.json`.
|
|
2
|
+
//
|
|
3
|
+
// Writing codex's user-level hooks file does not arm it — every new or changed
|
|
4
|
+
// hook needs an interactive human review, persisted as a `trusted_hash`. Hooks
|
|
5
|
+
// that ship INSIDE a plugin skip that review ("Managed hooks are always on"),
|
|
6
|
+
// which is why this route exists at all.
|
|
7
|
+
//
|
|
8
|
+
// What the checkout can do, and what it deliberately cannot:
|
|
9
|
+
//
|
|
10
|
+
// · it CAN build the bundle — a directory with `.codex-plugin/plugin.json` whose
|
|
11
|
+
// `hooks` field points at a `hooks.json` in the same Claude-shaped dialect
|
|
12
|
+
// codex already reads (verified against codex-cli 0.147.0: its plugin
|
|
13
|
+
// validator's required fields, and its scaffold's own `"hooks": "./hooks.json"`);
|
|
14
|
+
// · it CANNOT install it. A codex plugin is installed THROUGH A MARKETPLACE
|
|
15
|
+
// (`codex plugin marketplace add` then `codex plugin install`), a step that is
|
|
16
|
+
// the person's to run in their own host. So this generates and reports; it
|
|
17
|
+
// never says the hooks are armed, and it never writes a trust hash — forging
|
|
18
|
+
// one would forge somebody's security decision.
|
|
19
|
+
/** The plugin's name, and the marker that says a bundle on disk is ours. */
|
|
20
|
+
export const CODEX_PLUGIN_NAME = "agent-workflow";
|
|
21
|
+
/** Where the bundle is generated, relative to home. */
|
|
22
|
+
export const CODEX_PLUGIN_DIR = [".agent-workflow", "codex-plugin"];
|
|
23
|
+
/** `interface.category` — one of the values codex's validator accepts. */
|
|
24
|
+
const CATEGORY = "Productivity";
|
|
25
|
+
/**
|
|
26
|
+
* The bundle's files, built from the same template every other host adapts.
|
|
27
|
+
*
|
|
28
|
+
* Codex's event enum covers all five template events and its handlers admit
|
|
29
|
+
* `command` AND `prompt`, so the hooks document is the template verbatim — this
|
|
30
|
+
* is the one host where nothing is lost in translation, and inventing a
|
|
31
|
+
* transform would only add a place for the two to disagree.
|
|
32
|
+
*/
|
|
33
|
+
export function buildCodexPluginBundle(template, version) {
|
|
34
|
+
const descriptor = {
|
|
35
|
+
name: CODEX_PLUGIN_NAME,
|
|
36
|
+
version: semverOrZero(version),
|
|
37
|
+
description: "Workline hooks for Codex, generated by the agent-workflow CLI",
|
|
38
|
+
author: { name: CODEX_PLUGIN_NAME },
|
|
39
|
+
hooks: "./hooks.json",
|
|
40
|
+
interface: {
|
|
41
|
+
displayName: "Workline",
|
|
42
|
+
shortDescription: "Workline's branch, SQL and commit guards inside Codex.",
|
|
43
|
+
longDescription: "Ships the agent-workflow hook set as plugin-bundled hooks, so the guards run without a per-hook trust review.",
|
|
44
|
+
developerName: CODEX_PLUGIN_NAME,
|
|
45
|
+
category: CATEGORY,
|
|
46
|
+
capabilities: [],
|
|
47
|
+
defaultPrompt: "Run my Workline flow.",
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
return {
|
|
51
|
+
files: {
|
|
52
|
+
".codex-plugin/plugin.json": `${JSON.stringify(descriptor, null, 2)}\n`,
|
|
53
|
+
"hooks.json": `${JSON.stringify(template, null, 2)}\n`,
|
|
54
|
+
},
|
|
55
|
+
install_commands: [
|
|
56
|
+
"codex plugin marketplace add <bundle path>",
|
|
57
|
+
`codex plugin install ${CODEX_PLUGIN_NAME}`,
|
|
58
|
+
],
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* `version` must be strict semver or codex's validator rejects the plugin.
|
|
63
|
+
*
|
|
64
|
+
* A version this CLI could not read comes back as `unknown`, and shipping that
|
|
65
|
+
* string would produce a bundle nobody can install — with an error about the
|
|
66
|
+
* version rather than about the read that failed.
|
|
67
|
+
*/
|
|
68
|
+
function semverOrZero(version) {
|
|
69
|
+
return /^\d+\.\d+\.\d+(?:[-+].*)?$/.test(version) ? version : "0.0.0";
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* True when the bundle at this path is the one WE generated.
|
|
73
|
+
*
|
|
74
|
+
* Read from the descriptor's `name`, never from the path: a directory the person
|
|
75
|
+
* put there themselves is not ours to delete because it sits where we would have
|
|
76
|
+
* written.
|
|
77
|
+
*/
|
|
78
|
+
export function isOurCodexPlugin(descriptorText) {
|
|
79
|
+
try {
|
|
80
|
+
const parsed = JSON.parse(descriptorText);
|
|
81
|
+
return parsed.name === CODEX_PLUGIN_NAME;
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=codex-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-plugin.js","sourceRoot":"","sources":["../../../src/application/self/codex-plugin.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,EAAE;AACF,+EAA+E;AAC/E,+EAA+E;AAC/E,8EAA8E;AAC9E,yCAAyC;AACzC,EAAE;AACF,6DAA6D;AAC7D,EAAE;AACF,kFAAkF;AAClF,8EAA8E;AAC9E,yEAAyE;AACzE,qFAAqF;AACrF,6EAA6E;AAC7E,kFAAkF;AAClF,8EAA8E;AAC9E,gFAAgF;AAChF,mDAAmD;AAInD,4EAA4E;AAC5E,MAAM,CAAC,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AAElD,uDAAuD;AACvD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,iBAAiB,EAAE,cAAc,CAAU,CAAC;AAE7E,0EAA0E;AAC1E,MAAM,QAAQ,GAAG,cAAc,CAAC;AAShC;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CACpC,QAAuB,EACvB,OAAe;IAEf,MAAM,UAAU,GAAG;QACjB,IAAI,EAAE,iBAAiB;QACvB,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC;QAC9B,WAAW,EAAE,+DAA+D;QAC5E,MAAM,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE;QACnC,KAAK,EAAE,cAAc;QACrB,SAAS,EAAE;YACT,WAAW,EAAE,UAAU;YACvB,gBAAgB,EAAE,wDAAwD;YAC1E,eAAe,EACb,+GAA+G;YACjH,aAAa,EAAE,iBAAiB;YAChC,QAAQ,EAAE,QAAQ;YAClB,YAAY,EAAE,EAAE;YAChB,aAAa,EAAE,uBAAuB;SACvC;KACF,CAAC;IACF,OAAO;QACL,KAAK,EAAE;YACL,2BAA2B,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI;YACvE,YAAY,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI;SACvD;QACD,gBAAgB,EAAE;YAChB,4CAA4C;YAC5C,wBAAwB,iBAAiB,EAAE;SAC5C;KACF,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,YAAY,CAAC,OAAe;IACnC,OAAO,4BAA4B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;AACxE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,cAAsB;IACrD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAuB,CAAC;QAChE,OAAO,MAAM,CAAC,IAAI,KAAK,iBAAiB,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// The vocabulary every hook dialect shares: what a transform could not carry,
|
|
2
|
+
// what it carried with something missing, and whose a command is.
|
|
3
|
+
//
|
|
4
|
+
// It sits apart from any one dialect because all three answers are the same
|
|
5
|
+
// question in every host — and the TOML transform owned them first only because
|
|
6
|
+
// Kimi Code was the first host that needed a dialect at all.
|
|
7
|
+
/**
|
|
8
|
+
* True when this command line invokes THIS CLI (and not a lookalike binary).
|
|
9
|
+
*
|
|
10
|
+
* OWNERSHIP IS BY DATA, NOT BY COMMENT: a host that re-serializes its own config
|
|
11
|
+
* drops every marker we could write, so what identifies our entries is the one
|
|
12
|
+
* thing that survives — every command we install invokes this CLI.
|
|
13
|
+
*/
|
|
14
|
+
export function isOurCommand(command) {
|
|
15
|
+
const trimmed = command.trimStart();
|
|
16
|
+
return trimmed === "agent-workflow" || trimmed.startsWith("agent-workflow ");
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=hooks-dialect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks-dialect.js","sourceRoot":"","sources":["../../../src/application/self/hooks-dialect.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,kEAAkE;AAClE,EAAE;AACF,4EAA4E;AAC5E,gFAAgF;AAChF,6DAA6D;AAmB7D;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IACpC,OAAO,OAAO,KAAK,gBAAgB,IAAI,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;AAC/E,CAAC"}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
// Transformation of the bundled hooks template into the two JSON dialects that
|
|
2
|
+
// are NOT Claude's, plus the ownership surgery each one needs.
|
|
3
|
+
//
|
|
4
|
+
// Neither host is a copy of the Claude file, and neither is a copy of the other:
|
|
5
|
+
//
|
|
6
|
+
// · Crush keeps `hooks` inside `crush.json` as `<Event> → HookConfig[]`, where a
|
|
7
|
+
// HookConfig is FLAT — `{command, matcher?, timeout?}` — and only `PreToolUse`
|
|
8
|
+
// exists (verified against the v0.89.0 binary: its embedded skill doc and its
|
|
9
|
+
// own JSON schema, `config.HookConfig`).
|
|
10
|
+
// · agy keeps ONE `hooks.json` whose top-level keys are hook NAMES, each mapping
|
|
11
|
+
// to per-event config: `PreToolUse`/`PostToolUse` use Claude's `matcher`+`hooks`
|
|
12
|
+
// grouping, `PreInvocation`/`PostInvocation`/`Stop` are flat handler lists, and
|
|
13
|
+
// `enabled: false` disables a named hook (verified against agy 1.0.16's bundled
|
|
14
|
+
// customization doc).
|
|
15
|
+
//
|
|
16
|
+
// What both share with the Kimi transform is the thing that matters: a matcher
|
|
17
|
+
// only travels when it means the same thing on the other side. Ours name Claude's
|
|
18
|
+
// tools (`Bash`, `Edit`); crush's are `bash`, `edit`, `write`, and agy's are its
|
|
19
|
+
// step types lowercased (`run_command`, `file_change`). Carrying ours verbatim
|
|
20
|
+
// would install a hook that never fires, and dropping the matcher would install
|
|
21
|
+
// one that fires on every tool — so an untranslatable matcher SKIPS its hook and
|
|
22
|
+
// says so.
|
|
23
|
+
import { isOurCommand } from "./hooks-dialect.js";
|
|
24
|
+
/** The only template event either host can carry. */
|
|
25
|
+
const CARRIED_EVENT = "PreToolUse";
|
|
26
|
+
/** Why the other four template events have nowhere to go, per host. */
|
|
27
|
+
const NO_EVENT = {
|
|
28
|
+
crush: "crush supports only PreToolUse, so this event has nowhere to go",
|
|
29
|
+
agy: "agy has no equivalent event: its Stop fires at the end of every turn, not at session close, and it exposes no compaction event",
|
|
30
|
+
};
|
|
31
|
+
/** The named hook agy's `hooks.json` keeps ours under. */
|
|
32
|
+
export const AGY_HOOK_NAME = "agent-workflow";
|
|
33
|
+
/**
|
|
34
|
+
* Our template's tool matchers in each host's own tool vocabulary.
|
|
35
|
+
*
|
|
36
|
+
* Keyed by the template's matcher verbatim so a matcher that changes in the
|
|
37
|
+
* bundle stops being translated instead of being translated wrongly — the
|
|
38
|
+
* transform then skips its hook and reports it, which is the loud failure.
|
|
39
|
+
*/
|
|
40
|
+
const TOOL_MATCHERS = {
|
|
41
|
+
// crush: edit · write · multiedit (no notebook tool). agy: file_change · edit_notebook.
|
|
42
|
+
"Edit|Write|MultiEdit|NotebookEdit": {
|
|
43
|
+
crush: "^(edit|write|multiedit)$",
|
|
44
|
+
agy: "^(file_change|edit_notebook)$",
|
|
45
|
+
},
|
|
46
|
+
// crush names MCP tools `mcp_<server>_<tool>`; agy's SQL step is `cloud_sql_execute_sql`.
|
|
47
|
+
"mcp__.*__execute_sql": { crush: "^mcp_.*_execute_sql$", agy: "^.*execute_sql$" },
|
|
48
|
+
Bash: { crush: "^bash$", agy: "^run_command$" },
|
|
49
|
+
};
|
|
50
|
+
/** Flattens the bundled template into crush's `hooks` map. */
|
|
51
|
+
export function hooksTemplateToCrush(template) {
|
|
52
|
+
const entries = [];
|
|
53
|
+
const skipped = collect(template, "crush", (matcher, hook) => {
|
|
54
|
+
entries.push({
|
|
55
|
+
...(matcher === undefined ? {} : { matcher }),
|
|
56
|
+
command: hook.command,
|
|
57
|
+
...(hook.timeout === undefined ? {} : { timeout: hook.timeout }),
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
return { emitted: entries.length === 0 ? {} : { [CARRIED_EVENT]: entries }, skipped };
|
|
61
|
+
}
|
|
62
|
+
/** Flattens the bundled template into agy's single named hook. */
|
|
63
|
+
export function hooksTemplateToAgy(template) {
|
|
64
|
+
const groups = [];
|
|
65
|
+
const skipped = collect(template, "agy", (matcher, hook) => {
|
|
66
|
+
groups.push({
|
|
67
|
+
...(matcher === undefined ? {} : { matcher }),
|
|
68
|
+
hooks: [
|
|
69
|
+
{
|
|
70
|
+
type: "command",
|
|
71
|
+
command: hook.command,
|
|
72
|
+
...(hook.timeout === undefined ? {} : { timeout: hook.timeout }),
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
return { emitted: groups.length === 0 ? null : { PreToolUse: groups }, skipped };
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* The one walk both dialects share: everything that is not `PreToolUse` is
|
|
81
|
+
* skipped with its reason, and every surviving hook is handed back with the
|
|
82
|
+
* matcher this host understands.
|
|
83
|
+
*/
|
|
84
|
+
function collect(template, host, emit) {
|
|
85
|
+
const skipped = [];
|
|
86
|
+
for (const [event, groups] of Object.entries(template.hooks)) {
|
|
87
|
+
if (event !== CARRIED_EVENT) {
|
|
88
|
+
skipped.push({ event, reason: NO_EVENT[host] });
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
for (const reason of carry(groups, host, emit)) {
|
|
92
|
+
skipped.push({ event, reason });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return skipped;
|
|
96
|
+
}
|
|
97
|
+
/** The `PreToolUse` groups, emitted one by one; the refusals come back as reasons. */
|
|
98
|
+
function carry(groups, host, emit) {
|
|
99
|
+
const refusals = [];
|
|
100
|
+
for (const group of groups) {
|
|
101
|
+
const matcher = translateMatcher(group.matcher, host);
|
|
102
|
+
for (const hook of group.hooks ?? []) {
|
|
103
|
+
const refusal = refuse(group, hook, matcher);
|
|
104
|
+
if (refusal === null)
|
|
105
|
+
emit(matcher ?? undefined, hook);
|
|
106
|
+
else
|
|
107
|
+
refusals.push(refusal);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return refusals;
|
|
111
|
+
}
|
|
112
|
+
/** Why this hook cannot travel, or `null` when it can. */
|
|
113
|
+
function refuse(group, hook, matcher) {
|
|
114
|
+
if (typeof hook.command !== "string" || hook.command.length === 0) {
|
|
115
|
+
return `hook of type '${hook.type}' has no command — this host only runs command hooks`;
|
|
116
|
+
}
|
|
117
|
+
if (matcher === null) {
|
|
118
|
+
return `matcher '${group.matcher}' has no equivalent in this host's tool names; carrying it would install a hook that never fires and dropping it would fire on every tool`;
|
|
119
|
+
}
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* The matcher that travels: the host's own regex, `undefined` when the group had
|
|
124
|
+
* none (which already means "every tool" on both sides), or `null` when one
|
|
125
|
+
* existed and cannot be translated.
|
|
126
|
+
*/
|
|
127
|
+
function translateMatcher(matcher, host) {
|
|
128
|
+
if (matcher === undefined || matcher.trim().length === 0)
|
|
129
|
+
return undefined;
|
|
130
|
+
const translation = TOOL_MATCHERS[matcher];
|
|
131
|
+
return translation === undefined ? null : translation[host];
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Removes our entries from a parsed `crush.json`, per ENTRY and never per event:
|
|
135
|
+
* a user with their own `PreToolUse` hook keeps it. An event left with nothing,
|
|
136
|
+
* and a `hooks` key left with no event, are dropped so repeated cycles cannot
|
|
137
|
+
* grow the file.
|
|
138
|
+
*/
|
|
139
|
+
export function stripOurCrushHooks(config) {
|
|
140
|
+
const hooks = asRecord(config.hooks);
|
|
141
|
+
if (hooks === null)
|
|
142
|
+
return { value: config, removed: 0, preserved: 0 };
|
|
143
|
+
const next = {};
|
|
144
|
+
let removed = 0;
|
|
145
|
+
let preserved = 0;
|
|
146
|
+
for (const [event, value] of Object.entries(hooks)) {
|
|
147
|
+
if (!Array.isArray(value)) {
|
|
148
|
+
next[event] = value;
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
const kept = value.filter((entry) => !isOurHookEntry(entry));
|
|
152
|
+
removed += value.length - kept.length;
|
|
153
|
+
preserved += kept.length;
|
|
154
|
+
if (kept.length > 0)
|
|
155
|
+
next[event] = kept;
|
|
156
|
+
}
|
|
157
|
+
if (removed === 0)
|
|
158
|
+
return { value: config, removed: 0, preserved };
|
|
159
|
+
const { hooks: _dropped, ...rest } = config;
|
|
160
|
+
const value = Object.keys(next).length > 0 ? { ...rest, hooks: next } : rest;
|
|
161
|
+
return { value, removed, preserved };
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Removes our named hook from a parsed `hooks.json`, and only when EVERY command
|
|
165
|
+
* under it is ours. A named hook someone else wrote under the same name is left
|
|
166
|
+
* alone: the name is where we put ours, never proof that ours is what is there.
|
|
167
|
+
*/
|
|
168
|
+
export function stripOurAgyHooks(doc) {
|
|
169
|
+
const named = asRecord(doc[AGY_HOOK_NAME]);
|
|
170
|
+
const preserved = Object.keys(doc).length - (named === null ? 0 : 1);
|
|
171
|
+
if (named === null)
|
|
172
|
+
return { value: doc, removed: 0, preserved };
|
|
173
|
+
const commands = agyCommands(named);
|
|
174
|
+
if (commands.length === 0 || !commands.every(isOurCommand)) {
|
|
175
|
+
return { value: doc, removed: 0, preserved: preserved + 1 };
|
|
176
|
+
}
|
|
177
|
+
const { [AGY_HOOK_NAME]: _ours, ...rest } = doc;
|
|
178
|
+
return { value: rest, removed: commands.length, preserved };
|
|
179
|
+
}
|
|
180
|
+
/** How many of our hook entries a parsed `crush.json` declares. */
|
|
181
|
+
export function countOurCrushHooks(config) {
|
|
182
|
+
const hooks = asRecord(config.hooks);
|
|
183
|
+
if (hooks === null)
|
|
184
|
+
return 0;
|
|
185
|
+
let count = 0;
|
|
186
|
+
for (const value of Object.values(hooks)) {
|
|
187
|
+
if (Array.isArray(value))
|
|
188
|
+
count += value.filter(isOurHookEntry).length;
|
|
189
|
+
}
|
|
190
|
+
return count;
|
|
191
|
+
}
|
|
192
|
+
/** How many of our hook handlers a parsed `hooks.json` declares under our name. */
|
|
193
|
+
export function countOurAgyHooks(doc) {
|
|
194
|
+
const named = asRecord(doc[AGY_HOOK_NAME]);
|
|
195
|
+
if (named === null)
|
|
196
|
+
return 0;
|
|
197
|
+
return agyCommands(named).filter(isOurCommand).length;
|
|
198
|
+
}
|
|
199
|
+
function agyCommands(named) {
|
|
200
|
+
const groups = named[CARRIED_EVENT];
|
|
201
|
+
if (!Array.isArray(groups))
|
|
202
|
+
return [];
|
|
203
|
+
const out = [];
|
|
204
|
+
for (const group of groups) {
|
|
205
|
+
const hooks = asRecord(group)?.hooks;
|
|
206
|
+
if (!Array.isArray(hooks))
|
|
207
|
+
continue;
|
|
208
|
+
for (const hook of hooks) {
|
|
209
|
+
const command = asRecord(hook)?.command;
|
|
210
|
+
if (typeof command === "string")
|
|
211
|
+
out.push(command);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return out;
|
|
215
|
+
}
|
|
216
|
+
/** True when this flat `{command, …}` entry is one WE installed. */
|
|
217
|
+
export function isOurHookEntry(entry) {
|
|
218
|
+
const command = asRecord(entry)?.command;
|
|
219
|
+
return typeof command === "string" && isOurCommand(command);
|
|
220
|
+
}
|
|
221
|
+
function asRecord(value) {
|
|
222
|
+
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
223
|
+
? value
|
|
224
|
+
: null;
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=hooks-json.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks-json.js","sourceRoot":"","sources":["../../../src/application/self/hooks-json.ts"],"names":[],"mappings":"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"}
|