@telora/daemon 0.20.78 → 0.20.95
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/build-info.json +2 -2
- package/dist/ai-inspection-context.d.ts.map +1 -1
- package/dist/ai-inspection-context.js +4 -2
- package/dist/ai-inspection-context.js.map +1 -1
- package/dist/audit-prompt.d.ts.map +1 -1
- package/dist/audit-prompt.js +9 -5
- package/dist/audit-prompt.js.map +1 -1
- package/dist/ci-sensor-loop.d.ts +33 -5
- package/dist/ci-sensor-loop.d.ts.map +1 -1
- package/dist/ci-sensor-loop.js +95 -14
- package/dist/ci-sensor-loop.js.map +1 -1
- package/dist/ci-status-git.d.ts +7 -5
- package/dist/ci-status-git.d.ts.map +1 -1
- package/dist/ci-status-git.js +12 -9
- package/dist/ci-status-git.js.map +1 -1
- package/dist/ci-status.d.ts +21 -6
- package/dist/ci-status.d.ts.map +1 -1
- package/dist/ci-status.js +90 -15
- package/dist/ci-status.js.map +1 -1
- package/dist/cli/connect/agents.d.ts +64 -14
- package/dist/cli/connect/agents.d.ts.map +1 -1
- package/dist/cli/connect/agents.js +102 -19
- package/dist/cli/connect/agents.js.map +1 -1
- package/dist/cli/connect/claude.d.ts +19 -16
- package/dist/cli/connect/claude.d.ts.map +1 -1
- package/dist/cli/connect/claude.js +34 -68
- package/dist/cli/connect/claude.js.map +1 -1
- package/dist/cli/connect/scaffolding.d.ts +3 -2
- package/dist/cli/connect/scaffolding.d.ts.map +1 -1
- package/dist/cli/connect/scaffolding.js +17 -6
- package/dist/cli/connect/scaffolding.js.map +1 -1
- package/dist/cli/connect/seed-retirement.d.ts +39 -0
- package/dist/cli/connect/seed-retirement.d.ts.map +1 -0
- package/dist/cli/connect/seed-retirement.js +95 -0
- package/dist/cli/connect/seed-retirement.js.map +1 -0
- package/dist/cli/connect.d.ts +2 -2
- package/dist/cli/connect.d.ts.map +1 -1
- package/dist/cli/connect.js +8 -2
- package/dist/cli/connect.js.map +1 -1
- package/dist/cli/session-state.d.ts +0 -20
- package/dist/cli/session-state.d.ts.map +1 -1
- package/dist/cli/session-state.js +20 -49
- package/dist/cli/session-state.js.map +1 -1
- package/dist/completion/completion-decision.d.ts +3 -29
- package/dist/completion/completion-decision.d.ts.map +1 -1
- package/dist/completion/completion-decision.js +3 -15
- package/dist/completion/completion-decision.js.map +1 -1
- package/dist/completion/event-phases.d.ts +0 -8
- package/dist/completion/event-phases.d.ts.map +1 -1
- package/dist/completion/event-phases.js +4 -52
- package/dist/completion/event-phases.js.map +1 -1
- package/dist/completion/event.d.ts +1 -11
- package/dist/completion/event.d.ts.map +1 -1
- package/dist/completion/event.js +1 -3
- package/dist/completion/event.js.map +1 -1
- package/dist/completion/merge-phase.d.ts +1 -1
- package/dist/completion/merge-phase.d.ts.map +1 -1
- package/dist/completion/merge-phase.js +14 -34
- package/dist/completion/merge-phase.js.map +1 -1
- package/dist/completion/team-lifecycle.d.ts.map +1 -1
- package/dist/completion/team-lifecycle.js +13 -1
- package/dist/completion/team-lifecycle.js.map +1 -1
- package/dist/delivery-artifacts.d.ts.map +1 -1
- package/dist/delivery-artifacts.js +9 -8
- package/dist/delivery-artifacts.js.map +1 -1
- package/dist/git/merge.d.ts +16 -0
- package/dist/git/merge.d.ts.map +1 -1
- package/dist/git/merge.js +39 -1
- package/dist/git/merge.js.map +1 -1
- package/dist/product-scaffold.d.ts +8 -6
- package/dist/product-scaffold.d.ts.map +1 -1
- package/dist/product-scaffold.js +14 -10
- package/dist/product-scaffold.js.map +1 -1
- package/dist/prompt-sections/execution-sections.d.ts.map +1 -1
- package/dist/prompt-sections/execution-sections.js +44 -3
- package/dist/prompt-sections/execution-sections.js.map +1 -1
- package/dist/prompt-sections/scoping-sections.d.ts.map +1 -1
- package/dist/prompt-sections/scoping-sections.js +8 -0
- package/dist/prompt-sections/scoping-sections.js.map +1 -1
- package/dist/queries/cause-key.d.ts +13 -3
- package/dist/queries/cause-key.d.ts.map +1 -1
- package/dist/queries/cause-key.js +14 -4
- package/dist/queries/cause-key.js.map +1 -1
- package/dist/queries/deliveries.d.ts +20 -153
- package/dist/queries/deliveries.d.ts.map +1 -1
- package/dist/queries/deliveries.js +26 -0
- package/dist/queries/deliveries.js.map +1 -1
- package/dist/queries/delivery-gate-state.d.ts +192 -0
- package/dist/queries/delivery-gate-state.d.ts.map +1 -0
- package/dist/queries/delivery-gate-state.js +23 -0
- package/dist/queries/delivery-gate-state.js.map +1 -0
- package/dist/queries/holds.d.ts +62 -60
- package/dist/queries/holds.d.ts.map +1 -1
- package/dist/queries/holds.js +70 -69
- package/dist/queries/holds.js.map +1 -1
- package/dist/queries/issues.d.ts +2 -2
- package/dist/queries/issues.d.ts.map +1 -1
- package/dist/queries/issues.js +2 -2
- package/dist/queries/issues.js.map +1 -1
- package/dist/reality-pole.d.ts +5 -3
- package/dist/reality-pole.d.ts.map +1 -1
- package/dist/reality-pole.js +13 -4
- package/dist/reality-pole.js.map +1 -1
- package/dist/resolvers/git-diff-against-base.d.ts.map +1 -1
- package/dist/resolvers/git-diff-against-base.js +12 -5
- package/dist/resolvers/git-diff-against-base.js.map +1 -1
- package/dist/resolvers/index.d.ts +1 -1
- package/dist/resolvers/index.d.ts.map +1 -1
- package/dist/resolvers/index.js +1 -1
- package/dist/resolvers/index.js.map +1 -1
- package/dist/resolvers/shared/git-diff.d.ts +147 -26
- package/dist/resolvers/shared/git-diff.d.ts.map +1 -1
- package/dist/resolvers/shared/git-diff.js +275 -35
- package/dist/resolvers/shared/git-diff.js.map +1 -1
- package/dist/templates/agents-md.d.ts +16 -0
- package/dist/templates/agents-md.d.ts.map +1 -1
- package/dist/templates/agents-md.js +26 -0
- package/dist/templates/agents-md.js.map +1 -1
- package/dist/templates/claude-settings.d.ts +44 -1
- package/dist/templates/claude-settings.d.ts.map +1 -1
- package/dist/templates/claude-settings.js +73 -1
- package/dist/templates/claude-settings.js.map +1 -1
- package/dist/unified-shell-provisioning.d.ts +99 -0
- package/dist/unified-shell-provisioning.d.ts.map +1 -0
- package/dist/unified-shell-provisioning.js +222 -0
- package/dist/unified-shell-provisioning.js.map +1 -0
- package/dist/unified-shell.d.ts +0 -41
- package/dist/unified-shell.d.ts.map +1 -1
- package/dist/unified-shell.js +19 -135
- package/dist/unified-shell.js.map +1 -1
- package/dist/verification-deps.d.ts +151 -0
- package/dist/verification-deps.d.ts.map +1 -0
- package/dist/verification-deps.js +19 -0
- package/dist/verification-deps.js.map +1 -0
- package/dist/verification-engine.d.ts +10 -112
- package/dist/verification-engine.d.ts.map +1 -1
- package/dist/verification-engine.js +84 -30
- package/dist/verification-engine.js.map +1 -1
- package/dist/verification-evidence.d.ts +33 -1
- package/dist/verification-evidence.d.ts.map +1 -1
- package/dist/verification-evidence.js +55 -13
- package/dist/verification-evidence.js.map +1 -1
- package/dist/verification-feedback.d.ts +31 -27
- package/dist/verification-feedback.d.ts.map +1 -1
- package/dist/verification-feedback.js +76 -85
- package/dist/verification-feedback.js.map +1 -1
- package/dist/verify-restatement.d.ts +12 -9
- package/dist/verify-restatement.d.ts.map +1 -1
- package/dist/verify-restatement.js +11 -9
- package/dist/verify-restatement.js.map +1 -1
- package/package.json +1 -1
package/dist/ci-status.js
CHANGED
|
@@ -54,29 +54,104 @@ export function resolveCiMergeGate(status) {
|
|
|
54
54
|
return { proceed: false, status: 'unknown', reason: 'CI status unavailable for the merged SHA -- holding (fail-closed: unknown != green)' };
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
+
/** The recognized state a ci-status ref suffix encodes, or null if unrecognized. */
|
|
58
|
+
function ciStateFromRefSuffix(ref) {
|
|
59
|
+
if (ref.endsWith('/failure') || ref.endsWith('/error') || ref.endsWith('/red'))
|
|
60
|
+
return 'red';
|
|
61
|
+
if (ref.endsWith('/success') || ref.endsWith('/green') || ref.endsWith('/passed'))
|
|
62
|
+
return 'green';
|
|
63
|
+
if (ref.endsWith('/pending') || ref.endsWith('/running') || ref.endsWith('/queued'))
|
|
64
|
+
return 'pending';
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The run-ordering token a NEW ref carries, or null for a legacy ref.
|
|
69
|
+
*
|
|
70
|
+
* New scheme: `refs/ci-status/<sha>/<runNumber>/<state>` (5 slash-parts) -- the
|
|
71
|
+
* run number is parts[3]. Legacy scheme: `refs/ci-status/<sha>/<state>` (4
|
|
72
|
+
* parts) carries no order. Disambiguated by SEGMENT COUNT, not by numeric-ness,
|
|
73
|
+
* so an all-digit sha in a legacy ref is never mistaken for a run number.
|
|
74
|
+
*/
|
|
75
|
+
function ciRunOrderFromRef(ref) {
|
|
76
|
+
const parts = ref.split('/');
|
|
77
|
+
if (parts.length === 5 && parts[1] === 'ci-status') {
|
|
78
|
+
const token = parts[3];
|
|
79
|
+
if (token !== undefined && /^[0-9]+$/.test(token)) {
|
|
80
|
+
const n = Number(token);
|
|
81
|
+
return Number.isSafeInteger(n) ? n : null;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
57
86
|
/**
|
|
58
|
-
* Classify a git-native CI status from the set of
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
87
|
+
* Classify a git-native CI status from the set of ci-status ref names published
|
|
88
|
+
* for a SHA. The STATE is encoded in the ref NAME (immutable per-SHA), so no
|
|
89
|
+
* object content read is needed. Pure -- the caller supplies the ref names from a
|
|
90
|
+
* scoped `git ls-remote` / fetch.
|
|
91
|
+
*
|
|
92
|
+
* MOST-RECENT-RUN-WINS. The publisher encodes run order in the ref PATH
|
|
93
|
+
* (`refs/ci-status/<sha>/<runNumber>/<state>`), so a later GREEN run's ref
|
|
94
|
+
* outranks an earlier FAILURE ref for the same sha. This fixes the "a failure
|
|
95
|
+
* ref outranks a success ref, forever" trap: ref names carried no order, so a
|
|
96
|
+
* sha that once published a failure (an infra blip, or an evicted run) stayed
|
|
97
|
+
* red permanently even after a real green run of the same sha. The order comes
|
|
98
|
+
* from the workflow, never inferred by this reader.
|
|
99
|
+
*
|
|
100
|
+
* FAIL-CLOSED throughout: an empty set / unrecognized suffix -> 'unknown'
|
|
101
|
+
* (holds); among the highest run number, RED wins on a tie (the rare same-run
|
|
102
|
+
* re-run that published both states resolves to red, never a false green).
|
|
103
|
+
*
|
|
104
|
+
* LEGACY refs (`refs/ci-status/<sha>/<state>`, no run number) carry no order; if
|
|
105
|
+
* ONLY legacy refs exist we fall back to the original fail-closed precedence
|
|
106
|
+
* (failure outranks success outranks pending), preserving prior behavior for
|
|
107
|
+
* shas published before the run-ordered scheme deployed.
|
|
64
108
|
*/
|
|
65
109
|
export function classifyGitNativeCiStatus(refNames) {
|
|
66
|
-
let
|
|
67
|
-
|
|
110
|
+
let bestOrder = -1;
|
|
111
|
+
const statesAtBest = new Set();
|
|
112
|
+
let sawLegacyRed = false;
|
|
113
|
+
let sawLegacyGreen = false;
|
|
114
|
+
let sawLegacyPending = false;
|
|
68
115
|
for (const raw of refNames) {
|
|
69
116
|
const ref = raw.trim();
|
|
70
|
-
|
|
117
|
+
const state = ciStateFromRefSuffix(ref);
|
|
118
|
+
if (!state)
|
|
119
|
+
continue;
|
|
120
|
+
const order = ciRunOrderFromRef(ref);
|
|
121
|
+
if (order === null) {
|
|
122
|
+
if (state === 'red')
|
|
123
|
+
sawLegacyRed = true;
|
|
124
|
+
else if (state === 'green')
|
|
125
|
+
sawLegacyGreen = true;
|
|
126
|
+
else
|
|
127
|
+
sawLegacyPending = true;
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
if (order > bestOrder) {
|
|
131
|
+
bestOrder = order;
|
|
132
|
+
statesAtBest.clear();
|
|
133
|
+
statesAtBest.add(state);
|
|
134
|
+
}
|
|
135
|
+
else if (order === bestOrder) {
|
|
136
|
+
statesAtBest.add(state);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// Most-recent ordered run decides (red wins a same-run tie, fail-closed).
|
|
140
|
+
if (bestOrder >= 0) {
|
|
141
|
+
if (statesAtBest.has('red'))
|
|
71
142
|
return 'red';
|
|
72
|
-
if (
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
143
|
+
if (statesAtBest.has('green'))
|
|
144
|
+
return 'green';
|
|
145
|
+
if (statesAtBest.has('pending'))
|
|
146
|
+
return 'pending';
|
|
147
|
+
return 'unknown';
|
|
76
148
|
}
|
|
77
|
-
|
|
149
|
+
// Legacy-only fallback: original fail-closed precedence.
|
|
150
|
+
if (sawLegacyRed)
|
|
151
|
+
return 'red';
|
|
152
|
+
if (sawLegacyGreen)
|
|
78
153
|
return 'green';
|
|
79
|
-
if (
|
|
154
|
+
if (sawLegacyPending)
|
|
80
155
|
return 'pending';
|
|
81
156
|
return 'unknown';
|
|
82
157
|
}
|
package/dist/ci-status.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ci-status.js","sourceRoot":"","sources":["../src/ci-status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAyBH;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAmB;IACpD,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,OAAO;YACV,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,6BAA6B,EAAE,CAAC;QAC1E,KAAK,SAAS;YACZ,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,4EAA4E,EAAE,CAAC;QAC1H,KAAK,KAAK;YACR,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,wFAAwF,EAAE,CAAC;QACtI,KAAK,SAAS,CAAC;QACf;YACE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,qFAAqF,EAAE,CAAC;IAChJ,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,yBAAyB,CAAC,QAA2B;IACnE,IAAI,
|
|
1
|
+
{"version":3,"file":"ci-status.js","sourceRoot":"","sources":["../src/ci-status.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,24 +1,74 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Codex/IDE harness config writer: the seeded `AGENTS.md` block.
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Codex/IDE harness config writer: the seeded `AGENTS.md` block.
|
|
3
|
+
*
|
|
4
|
+
* Codex has no SessionStart hook, so its seed cannot ride the harness the way
|
|
5
|
+
* the Claude seed does -- it needs a FILE carrier, and that file must live off
|
|
6
|
+
* the repo root so the connector never fights the repo for `<repo>/AGENTS.md`.
|
|
7
|
+
* There are three carriers, one per consumer:
|
|
8
|
+
*
|
|
9
|
+
* - `writeProductCodexAgentsMd` -> the daemon's ISOLATED PER-PRODUCT CODEX_HOME
|
|
10
|
+
* (`~/.telora/codex/<productId>/AGENTS.md`, resolveProductCodexHome). Read by
|
|
11
|
+
* daemon-spawned LOCAL-MODEL Codex agents (whose CODEX_HOME is redirected
|
|
12
|
+
* there at spawn). Being per-product, it carries the baked per-product
|
|
13
|
+
* connection-invariant header correctly.
|
|
14
|
+
* - `writeOrMergeGlobalAgentsMd` -> the operator's own `~/.codex/AGENTS.md`
|
|
15
|
+
* (globalAgentsMdPath). Read by an INTERACTIVE operator running Codex AND by
|
|
16
|
+
* daemon-spawned HOSTED Codex agents (whose ChatGPT-account auth lives in
|
|
17
|
+
* `~/.codex/auth.json`, so their CODEX_HOME cannot be redirected without
|
|
18
|
+
* breaking auth). Workstation-shared across products, so it carries the
|
|
19
|
+
* HEADER-LESS seed (identity resolved on demand via `telora-daemon status`).
|
|
20
|
+
* - `writeOrMergeAgentsMd` -> a REPO-ROOT `<repo>/AGENTS.md` for the IDE
|
|
21
|
+
* harnesses (Cursor / VS Code) that read it natively and have no off-repo
|
|
22
|
+
* carrier. Made SAFE: it never creates or appends where the repo TRACKS
|
|
23
|
+
* AGENTS.md -- it reports that state instead, so it cannot dirty tracked
|
|
24
|
+
* content and reproduce this focus's original bug.
|
|
25
|
+
*
|
|
26
|
+
* `retireAgentsMdSeed` removes a connector-written repo-root AGENTS.md block the
|
|
27
|
+
* Codex file-writer era left behind.
|
|
5
28
|
*/
|
|
6
29
|
import { type AgentsMdConnectionInvariant } from '../../templates/agents-md.js';
|
|
7
30
|
import type { ConnectIO } from './shared.js';
|
|
8
31
|
/**
|
|
9
|
-
*
|
|
32
|
+
* The workstation-shared operator Codex AGENTS.md path: `$CODEX_HOME/AGENTS.md`,
|
|
33
|
+
* with CODEX_HOME defaulting to `~/.codex`. This is the location an interactive
|
|
34
|
+
* Codex session (and a hosted daemon spawn) reads global instructions from.
|
|
35
|
+
*/
|
|
36
|
+
export declare function globalAgentsMdPath(): string;
|
|
37
|
+
/**
|
|
38
|
+
* Write or merge the PER-PRODUCT Codex seed into the isolated CODEX_HOME
|
|
39
|
+
* (`~/.telora/codex/<productId>/AGENTS.md`). This is the carrier a daemon-spawned
|
|
40
|
+
* LOCAL-MODEL Codex agent reads (its CODEX_HOME is redirected there at spawn).
|
|
41
|
+
* The destination is genuinely per-product, so the baked connection-invariant
|
|
42
|
+
* header stays correct -- `renderAgentsMd(inv)` is reused unchanged.
|
|
43
|
+
*/
|
|
44
|
+
export declare function writeProductCodexAgentsMd(inv: AgentsMdConnectionInvariant, io: ConnectIO): void;
|
|
45
|
+
/**
|
|
46
|
+
* Write or merge the workstation-shared operator Codex seed at
|
|
47
|
+
* `$CODEX_HOME/AGENTS.md` (default `~/.codex/AGENTS.md`).
|
|
10
48
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
|
|
49
|
+
* Read by an interactive operator running Codex AND by daemon-spawned HOSTED
|
|
50
|
+
* Codex agents (whose auth lives in `~/.codex` and whose CODEX_HOME therefore
|
|
51
|
+
* cannot be redirected). Header-LESS: one workstation hosts many products, so
|
|
52
|
+
* this shared file cannot bake a correct per-product header -- the identity is
|
|
53
|
+
* resolved on demand via `telora-daemon status`.
|
|
54
|
+
*/
|
|
55
|
+
export declare function writeOrMergeGlobalAgentsMd(io: ConnectIO): void;
|
|
56
|
+
/**
|
|
57
|
+
* Write or merge a seeded `AGENTS.md` at the repo root, SAFELY (IDE harnesses).
|
|
17
58
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
59
|
+
* Cursor / VS Code read a repo-root AGENTS.md natively and have no off-repo
|
|
60
|
+
* carrier, so those harnesses still seed one -- but never at the cost of dirtying
|
|
61
|
+
* tracked content. If the repo TRACKS AGENTS.md, this REPORTS that state and
|
|
62
|
+
* writes nothing (the repo owns its tracked file). Only an absent or untracked
|
|
63
|
+
* AGENTS.md is created / merged. The Codex harness NO LONGER writes here.
|
|
22
64
|
*/
|
|
23
65
|
export declare function writeOrMergeAgentsMd(repoPath: string, inv: AgentsMdConnectionInvariant, io: ConnectIO): void;
|
|
66
|
+
/**
|
|
67
|
+
* Retire a connector-written repo-root `AGENTS.md` seed block. The Codex path
|
|
68
|
+
* used to write one; the connector no longer owns `<repo>/AGENTS.md`, so this
|
|
69
|
+
* removes the block it left behind -- honoring the ownership asymmetry
|
|
70
|
+
* (connector-created file removed; repo-tracked file reported, never rewritten).
|
|
71
|
+
* See `retireSeedFile` for the three on-disk states handled.
|
|
72
|
+
*/
|
|
73
|
+
export declare function retireAgentsMdSeed(repoPath: string, io: ConnectIO): void;
|
|
24
74
|
//# sourceMappingURL=agents.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../../src/cli/connect/agents.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../../src/cli/connect/agents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAKH,OAAO,EAKL,KAAK,2BAA2B,EACjC,MAAM,8BAA8B,CAAC;AAGtC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAG3C;AAwDD;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,2BAA2B,EAAE,EAAE,EAAE,SAAS,GAAG,IAAI,CAG/F;AAED;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CAAC,EAAE,EAAE,SAAS,GAAG,IAAI,CAE9D;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,2BAA2B,EAChC,EAAE,EAAE,SAAS,GACZ,IAAI,CAUN;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,GAAG,IAAI,CAExE"}
|
|
@@ -1,30 +1,61 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Codex/IDE harness config writer: the seeded `AGENTS.md` block.
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Codex/IDE harness config writer: the seeded `AGENTS.md` block.
|
|
3
|
+
*
|
|
4
|
+
* Codex has no SessionStart hook, so its seed cannot ride the harness the way
|
|
5
|
+
* the Claude seed does -- it needs a FILE carrier, and that file must live off
|
|
6
|
+
* the repo root so the connector never fights the repo for `<repo>/AGENTS.md`.
|
|
7
|
+
* There are three carriers, one per consumer:
|
|
8
|
+
*
|
|
9
|
+
* - `writeProductCodexAgentsMd` -> the daemon's ISOLATED PER-PRODUCT CODEX_HOME
|
|
10
|
+
* (`~/.telora/codex/<productId>/AGENTS.md`, resolveProductCodexHome). Read by
|
|
11
|
+
* daemon-spawned LOCAL-MODEL Codex agents (whose CODEX_HOME is redirected
|
|
12
|
+
* there at spawn). Being per-product, it carries the baked per-product
|
|
13
|
+
* connection-invariant header correctly.
|
|
14
|
+
* - `writeOrMergeGlobalAgentsMd` -> the operator's own `~/.codex/AGENTS.md`
|
|
15
|
+
* (globalAgentsMdPath). Read by an INTERACTIVE operator running Codex AND by
|
|
16
|
+
* daemon-spawned HOSTED Codex agents (whose ChatGPT-account auth lives in
|
|
17
|
+
* `~/.codex/auth.json`, so their CODEX_HOME cannot be redirected without
|
|
18
|
+
* breaking auth). Workstation-shared across products, so it carries the
|
|
19
|
+
* HEADER-LESS seed (identity resolved on demand via `telora-daemon status`).
|
|
20
|
+
* - `writeOrMergeAgentsMd` -> a REPO-ROOT `<repo>/AGENTS.md` for the IDE
|
|
21
|
+
* harnesses (Cursor / VS Code) that read it natively and have no off-repo
|
|
22
|
+
* carrier. Made SAFE: it never creates or appends where the repo TRACKS
|
|
23
|
+
* AGENTS.md -- it reports that state instead, so it cannot dirty tracked
|
|
24
|
+
* content and reproduce this focus's original bug.
|
|
25
|
+
*
|
|
26
|
+
* `retireAgentsMdSeed` removes a connector-written repo-root AGENTS.md block the
|
|
27
|
+
* Codex file-writer era left behind.
|
|
5
28
|
*/
|
|
6
|
-
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
29
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
30
|
+
import { homedir } from 'node:os';
|
|
31
|
+
import { dirname, join, resolve } from 'node:path';
|
|
32
|
+
import { TELORA_AGENTS_MD_BEGIN, TELORA_AGENTS_MD_END, renderAgentsMd, renderCodexOperatorSeed, } from '../../templates/agents-md.js';
|
|
33
|
+
import { resolveProductCodexHome } from '../codex-provision.js';
|
|
34
|
+
import { isPathTracked, retireSeedFile } from './seed-retirement.js';
|
|
9
35
|
/**
|
|
10
|
-
*
|
|
36
|
+
* The workstation-shared operator Codex AGENTS.md path: `$CODEX_HOME/AGENTS.md`,
|
|
37
|
+
* with CODEX_HOME defaulting to `~/.codex`. This is the location an interactive
|
|
38
|
+
* Codex session (and a hosted daemon spawn) reads global instructions from.
|
|
39
|
+
*/
|
|
40
|
+
export function globalAgentsMdPath() {
|
|
41
|
+
const codexHome = process.env.CODEX_HOME || join(homedir(), '.codex');
|
|
42
|
+
return join(codexHome, 'AGENTS.md');
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Core delimited-block merge for an AGENTS.md at an absolute path, given a
|
|
46
|
+
* pre-rendered seed block.
|
|
11
47
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* -
|
|
16
|
-
* block at the end; user content untouched.
|
|
17
|
-
* - Existing AGENTS.md WITH the delimiters: replaces only the delimited block.
|
|
48
|
+
* - No file: writes the seeded block straight in (creating the parent dir).
|
|
49
|
+
* - File without the Telora delimiters: appends a delimited block; user
|
|
50
|
+
* content untouched.
|
|
51
|
+
* - File WITH the delimiters: replaces only the delimited block.
|
|
18
52
|
*
|
|
19
53
|
* Idempotent at the filesystem level: when the computed content equals what is
|
|
20
|
-
* already on disk, NO write occurs (no spurious mtime bump, no git churn).
|
|
21
|
-
* daemon re-invokes this on boot to self-heal the seed block, so the
|
|
22
|
-
* unchanged-common-case must not touch the file.
|
|
54
|
+
* already on disk, NO write occurs (no spurious mtime bump, no git churn).
|
|
23
55
|
*/
|
|
24
|
-
|
|
25
|
-
const path = resolve(repoPath, 'AGENTS.md');
|
|
26
|
-
const seedBlock = renderAgentsMd(inv);
|
|
56
|
+
function writeOrMergeAgentsBlockAt(path, seedBlock, io) {
|
|
27
57
|
if (!existsSync(path)) {
|
|
58
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
28
59
|
writeFileSync(path, seedBlock);
|
|
29
60
|
io.out(`Wrote ${path}.\n`);
|
|
30
61
|
return;
|
|
@@ -62,4 +93,56 @@ export function writeOrMergeAgentsMd(repoPath, inv, io) {
|
|
|
62
93
|
writeFileSync(path, newContent);
|
|
63
94
|
io.out(message);
|
|
64
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* Write or merge the PER-PRODUCT Codex seed into the isolated CODEX_HOME
|
|
98
|
+
* (`~/.telora/codex/<productId>/AGENTS.md`). This is the carrier a daemon-spawned
|
|
99
|
+
* LOCAL-MODEL Codex agent reads (its CODEX_HOME is redirected there at spawn).
|
|
100
|
+
* The destination is genuinely per-product, so the baked connection-invariant
|
|
101
|
+
* header stays correct -- `renderAgentsMd(inv)` is reused unchanged.
|
|
102
|
+
*/
|
|
103
|
+
export function writeProductCodexAgentsMd(inv, io) {
|
|
104
|
+
const path = resolve(resolveProductCodexHome(inv.productId), 'AGENTS.md');
|
|
105
|
+
writeOrMergeAgentsBlockAt(path, renderAgentsMd(inv), io);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Write or merge the workstation-shared operator Codex seed at
|
|
109
|
+
* `$CODEX_HOME/AGENTS.md` (default `~/.codex/AGENTS.md`).
|
|
110
|
+
*
|
|
111
|
+
* Read by an interactive operator running Codex AND by daemon-spawned HOSTED
|
|
112
|
+
* Codex agents (whose auth lives in `~/.codex` and whose CODEX_HOME therefore
|
|
113
|
+
* cannot be redirected). Header-LESS: one workstation hosts many products, so
|
|
114
|
+
* this shared file cannot bake a correct per-product header -- the identity is
|
|
115
|
+
* resolved on demand via `telora-daemon status`.
|
|
116
|
+
*/
|
|
117
|
+
export function writeOrMergeGlobalAgentsMd(io) {
|
|
118
|
+
writeOrMergeAgentsBlockAt(globalAgentsMdPath(), renderCodexOperatorSeed(), io);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Write or merge a seeded `AGENTS.md` at the repo root, SAFELY (IDE harnesses).
|
|
122
|
+
*
|
|
123
|
+
* Cursor / VS Code read a repo-root AGENTS.md natively and have no off-repo
|
|
124
|
+
* carrier, so those harnesses still seed one -- but never at the cost of dirtying
|
|
125
|
+
* tracked content. If the repo TRACKS AGENTS.md, this REPORTS that state and
|
|
126
|
+
* writes nothing (the repo owns its tracked file). Only an absent or untracked
|
|
127
|
+
* AGENTS.md is created / merged. The Codex harness NO LONGER writes here.
|
|
128
|
+
*/
|
|
129
|
+
export function writeOrMergeAgentsMd(repoPath, inv, io) {
|
|
130
|
+
const path = resolve(repoPath, 'AGENTS.md');
|
|
131
|
+
if (existsSync(path) && isPathTracked(repoPath, 'AGENTS.md')) {
|
|
132
|
+
io.out(`AGENTS.md at ${path} is repo-tracked; leaving it to the repo (the ` +
|
|
133
|
+
`connector will not modify tracked content).\n`);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
writeOrMergeAgentsBlockAt(path, renderAgentsMd(inv), io);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Retire a connector-written repo-root `AGENTS.md` seed block. The Codex path
|
|
140
|
+
* used to write one; the connector no longer owns `<repo>/AGENTS.md`, so this
|
|
141
|
+
* removes the block it left behind -- honoring the ownership asymmetry
|
|
142
|
+
* (connector-created file removed; repo-tracked file reported, never rewritten).
|
|
143
|
+
* See `retireSeedFile` for the three on-disk states handled.
|
|
144
|
+
*/
|
|
145
|
+
export function retireAgentsMdSeed(repoPath, io) {
|
|
146
|
+
retireSeedFile(repoPath, 'AGENTS.md', TELORA_AGENTS_MD_BEGIN, TELORA_AGENTS_MD_END, io);
|
|
147
|
+
}
|
|
65
148
|
//# sourceMappingURL=agents.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../../../src/cli/connect/agents.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../../../src/cli/connect/agents.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,27 +5,30 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import type { ConnectIO } from './shared.js';
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Retire the connector-written `CLAUDE.md` seed block at the repo root.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* Idempotent at the filesystem level: when the computed content equals what
|
|
17
|
-
* is already on disk, NO write occurs (no spurious mtime bump, no git churn).
|
|
18
|
-
* The daemon re-invokes this on every boot to self-heal the seed block, so
|
|
19
|
-
* the unchanged-common-case must not touch the file.
|
|
10
|
+
* The Claude workstation seed is now workstation-scoped context delivered by the
|
|
11
|
+
* SessionStart hook (`telora-daemon session-state`), not a file the connector
|
|
12
|
+
* writes to the repo root -- so the connector stops owning `<repo>/CLAUDE.md`.
|
|
13
|
+
* This pass removes the delimited block it once wrote, honoring the ownership
|
|
14
|
+
* asymmetry (connector-created file -> removed; repo-tracked file -> reported,
|
|
15
|
+
* never rewritten). See `retireSeedFile` for the three on-disk states handled.
|
|
20
16
|
*/
|
|
21
|
-
export declare function
|
|
17
|
+
export declare function retireClaudeMdSeed(repoPath: string, io: ConnectIO): void;
|
|
22
18
|
/**
|
|
23
19
|
* Write or deep-merge `<repo>/.claude/settings.json`.
|
|
24
20
|
*
|
|
25
|
-
* Fresh: writes the template directly.
|
|
26
|
-
* Existing: deep-merges our `permissions.allow`
|
|
27
|
-
* settings, deduplicating. All other top-level keys are
|
|
28
|
-
* Re-runs produce no diff.
|
|
21
|
+
* Fresh: writes the template directly (creating `.claude/`).
|
|
22
|
+
* Existing: deep-merges our `permissions.allow` + the SessionStart seed hook
|
|
23
|
+
* into the user's settings, deduplicating. All other top-level keys are
|
|
24
|
+
* untouched. Re-runs produce no diff.
|
|
25
|
+
*
|
|
26
|
+
* Idempotent at the filesystem level: when the merged content equals what is
|
|
27
|
+
* already on disk, NO write occurs (no spurious mtime bump, no git churn). This
|
|
28
|
+
* matters because the daemon now re-invokes this on every boot
|
|
29
|
+
* (`refreshClaudeSettingsForProducts`) to migrate the SessionStart seed hook
|
|
30
|
+
* into already-connected repos -- the unchanged-common-case must not touch the
|
|
31
|
+
* file.
|
|
29
32
|
*/
|
|
30
33
|
export declare function writeOrMergeClaudeSettings(repoPath: string, io: ConnectIO): void;
|
|
31
34
|
//# sourceMappingURL=claude.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../../src/cli/connect/claude.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAaH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../../src/cli/connect/claude.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAaH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,GAAG,IAAI,CAExE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,GAAG,IAAI,CAiChF"}
|
|
@@ -5,88 +5,47 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
7
7
|
import { resolve } from 'node:path';
|
|
8
|
-
import { TELORA_CLAUDE_MD_BEGIN, TELORA_CLAUDE_MD_END,
|
|
8
|
+
import { TELORA_CLAUDE_MD_BEGIN, TELORA_CLAUDE_MD_END, } from '../../templates/claude-md.js';
|
|
9
9
|
import { buildClaudeSettings, mergeClaudeSettings, } from '../../templates/claude-settings.js';
|
|
10
|
+
import { retireSeedFile } from './seed-retirement.js';
|
|
10
11
|
/**
|
|
11
|
-
*
|
|
12
|
+
* Retire the connector-written `CLAUDE.md` seed block at the repo root.
|
|
12
13
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* Idempotent at the filesystem level: when the computed content equals what
|
|
20
|
-
* is already on disk, NO write occurs (no spurious mtime bump, no git churn).
|
|
21
|
-
* The daemon re-invokes this on every boot to self-heal the seed block, so
|
|
22
|
-
* the unchanged-common-case must not touch the file.
|
|
14
|
+
* The Claude workstation seed is now workstation-scoped context delivered by the
|
|
15
|
+
* SessionStart hook (`telora-daemon session-state`), not a file the connector
|
|
16
|
+
* writes to the repo root -- so the connector stops owning `<repo>/CLAUDE.md`.
|
|
17
|
+
* This pass removes the delimited block it once wrote, honoring the ownership
|
|
18
|
+
* asymmetry (connector-created file -> removed; repo-tracked file -> reported,
|
|
19
|
+
* never rewritten). See `retireSeedFile` for the three on-disk states handled.
|
|
23
20
|
*/
|
|
24
|
-
export function
|
|
25
|
-
|
|
26
|
-
const seedBlock = renderClaudeMd(productName);
|
|
27
|
-
if (!existsSync(path)) {
|
|
28
|
-
writeFileSync(path, seedBlock);
|
|
29
|
-
io.out(`Wrote ${path}.\n`);
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
const existing = readFileSync(path, 'utf-8');
|
|
33
|
-
const beginIdx = existing.indexOf(TELORA_CLAUDE_MD_BEGIN);
|
|
34
|
-
let newContent;
|
|
35
|
-
let message;
|
|
36
|
-
if (beginIdx === -1) {
|
|
37
|
-
// No prior Telora block -- append, preserving user content.
|
|
38
|
-
const sep = existing.endsWith('\n') ? '\n' : '\n\n';
|
|
39
|
-
newContent = existing + sep + seedBlock;
|
|
40
|
-
message = `Appended Telora seed block to ${path}.\n`;
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
const endIdx = existing.indexOf(TELORA_CLAUDE_MD_END, beginIdx);
|
|
44
|
-
if (endIdx === -1) {
|
|
45
|
-
// Begin marker without end -- treat as malformed. Append a fresh block
|
|
46
|
-
// rather than risk corrupting whatever's there.
|
|
47
|
-
const sep = existing.endsWith('\n') ? '\n' : '\n\n';
|
|
48
|
-
newContent = existing + sep + seedBlock;
|
|
49
|
-
message = `Appended Telora seed block to ${path} (prior block was malformed).\n`;
|
|
50
|
-
}
|
|
51
|
-
else {
|
|
52
|
-
// Replace the existing Telora block in place.
|
|
53
|
-
const after = endIdx + TELORA_CLAUDE_MD_END.length;
|
|
54
|
-
// Trim a trailing newline after the end marker so we don't accumulate
|
|
55
|
-
// blank lines on each re-run.
|
|
56
|
-
const trailingNewline = existing[after] === '\n' ? 1 : 0;
|
|
57
|
-
newContent =
|
|
58
|
-
existing.slice(0, beginIdx) +
|
|
59
|
-
seedBlock.trimEnd() +
|
|
60
|
-
'\n' +
|
|
61
|
-
existing.slice(after + trailingNewline);
|
|
62
|
-
message = `Refreshed Telora seed block in ${path}.\n`;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
// Idempotency guard: skip the write entirely when nothing would change.
|
|
66
|
-
// This keeps the boot-time self-heal a no-op for already-current repos.
|
|
67
|
-
if (newContent === existing)
|
|
68
|
-
return;
|
|
69
|
-
writeFileSync(path, newContent);
|
|
70
|
-
io.out(message);
|
|
21
|
+
export function retireClaudeMdSeed(repoPath, io) {
|
|
22
|
+
retireSeedFile(repoPath, 'CLAUDE.md', TELORA_CLAUDE_MD_BEGIN, TELORA_CLAUDE_MD_END, io);
|
|
71
23
|
}
|
|
72
24
|
/**
|
|
73
25
|
* Write or deep-merge `<repo>/.claude/settings.json`.
|
|
74
26
|
*
|
|
75
|
-
* Fresh: writes the template directly.
|
|
76
|
-
* Existing: deep-merges our `permissions.allow`
|
|
77
|
-
* settings, deduplicating. All other top-level keys are
|
|
78
|
-
* Re-runs produce no diff.
|
|
27
|
+
* Fresh: writes the template directly (creating `.claude/`).
|
|
28
|
+
* Existing: deep-merges our `permissions.allow` + the SessionStart seed hook
|
|
29
|
+
* into the user's settings, deduplicating. All other top-level keys are
|
|
30
|
+
* untouched. Re-runs produce no diff.
|
|
31
|
+
*
|
|
32
|
+
* Idempotent at the filesystem level: when the merged content equals what is
|
|
33
|
+
* already on disk, NO write occurs (no spurious mtime bump, no git churn). This
|
|
34
|
+
* matters because the daemon now re-invokes this on every boot
|
|
35
|
+
* (`refreshClaudeSettingsForProducts`) to migrate the SessionStart seed hook
|
|
36
|
+
* into already-connected repos -- the unchanged-common-case must not touch the
|
|
37
|
+
* file.
|
|
79
38
|
*/
|
|
80
39
|
export function writeOrMergeClaudeSettings(repoPath, io) {
|
|
81
40
|
const dir = resolve(repoPath, '.claude');
|
|
82
41
|
const path = resolve(dir, 'settings.json');
|
|
83
42
|
const seed = buildClaudeSettings();
|
|
84
|
-
if (!existsSync(dir))
|
|
85
|
-
mkdirSync(dir, { recursive: true });
|
|
86
43
|
let existing = null;
|
|
44
|
+
let existingRaw = null;
|
|
87
45
|
if (existsSync(path)) {
|
|
88
46
|
try {
|
|
89
|
-
|
|
47
|
+
existingRaw = readFileSync(path, 'utf-8');
|
|
48
|
+
const parsed = JSON.parse(existingRaw);
|
|
90
49
|
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
91
50
|
existing = parsed;
|
|
92
51
|
}
|
|
@@ -98,7 +57,14 @@ export function writeOrMergeClaudeSettings(repoPath, io) {
|
|
|
98
57
|
}
|
|
99
58
|
}
|
|
100
59
|
const merged = mergeClaudeSettings(existing, seed);
|
|
101
|
-
|
|
102
|
-
|
|
60
|
+
const nextRaw = JSON.stringify(merged, null, 2) + '\n';
|
|
61
|
+
// Idempotency guard: skip the write (and the dir mkdir) entirely when nothing
|
|
62
|
+
// would change, so the boot-cadence refresh is a pure no-op for current repos.
|
|
63
|
+
if (existingRaw !== null && nextRaw === existingRaw)
|
|
64
|
+
return;
|
|
65
|
+
if (!existsSync(dir))
|
|
66
|
+
mkdirSync(dir, { recursive: true });
|
|
67
|
+
writeFileSync(path, nextRaw);
|
|
68
|
+
io.out(existingRaw !== null ? `Merged Telora entries into ${path}.\n` : `Wrote ${path}.\n`);
|
|
103
69
|
}
|
|
104
70
|
//# sourceMappingURL=claude.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../../src/cli/connect/claude.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EACL,sBAAsB,EACtB,oBAAoB,
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../../src/cli/connect/claude.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EACL,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAgB,EAAE,EAAa;IAChE,cAAc,CAAC,QAAQ,EAAE,WAAW,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,EAAE,CAAC,CAAC;AAC1F,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,0BAA0B,CAAC,QAAgB,EAAE,EAAa;IACxE,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG,mBAAmB,EAAE,CAAC;IAEnC,IAAI,QAAQ,GAAmC,IAAI,CAAC;IACpD,IAAI,WAAW,GAAkB,IAAI,CAAC;IACtC,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACrB,IAAI,CAAC;YACH,WAAW,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YACvC,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBACnE,QAAQ,GAAG,MAAiC,CAAC;YAC/C,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,EAAE,CAAC,GAAG,CACJ,qBAAqB,IAAI,wCAAwC;gBAC/D,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAC1D,CAAC;YACF,OAAO;QACT,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,mBAAmB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACnD,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;IAEvD,8EAA8E;IAC9E,+EAA+E;IAC/E,IAAI,WAAW,KAAK,IAAI,IAAI,OAAO,KAAK,WAAW;QAAE,OAAO;IAE5D,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC7B,EAAE,CAAC,GAAG,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,8BAA8B,IAAI,KAAK,CAAC,CAAC,CAAC,SAAS,IAAI,KAAK,CAAC,CAAC;AAC9F,CAAC"}
|
|
@@ -18,8 +18,9 @@ export declare function harnessGitignoreEntries(harness: OperatorHarness): strin
|
|
|
18
18
|
* `connect --harness <h>` and the token-free `harness add <h>` verb produce
|
|
19
19
|
* byte-identical output for a given identity.
|
|
20
20
|
*
|
|
21
|
-
* - claude:
|
|
22
|
-
* - codex: AGENTS.md + Telora MCP in ~/.codex/config.toml
|
|
21
|
+
* - claude: .claude/settings.json (SessionStart seed hook) + retire any repo CLAUDE.md
|
|
22
|
+
* - codex: global $CODEX_HOME/AGENTS.md + Telora MCP in ~/.codex/config.toml
|
|
23
|
+
* (repo-root AGENTS.md seed retired)
|
|
23
24
|
* - cline: .cline/rules/telora.md + Telora MCP in ~/.cline settings
|
|
24
25
|
* - cursor: AGENTS.md + .cursor/mcp.json (preload env)
|
|
25
26
|
* - vscode: AGENTS.md + .vscode/mcp.json (preload env)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaffolding.d.ts","sourceRoot":"","sources":["../../../src/cli/connect/scaffolding.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,8BAA8B,CAAC;AAChF,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"scaffolding.d.ts","sourceRoot":"","sources":["../../../src/cli/connect/scaffolding.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,8BAA8B,CAAC;AAChF,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAU9D;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,EAAE,CAE1E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,eAAe,EACxB,GAAG,EAAE,2BAA2B,EAChC,EAAE,EAAE,SAAS,GACZ,IAAI,CAuBN"}
|