@telora/daemon 0.17.22 → 0.17.25
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/cli/session-state.d.ts +80 -4
- package/dist/cli/session-state.d.ts.map +1 -1
- package/dist/cli/session-state.js +130 -12
- package/dist/cli/session-state.js.map +1 -1
- package/dist/templates/claude-md.d.ts.map +1 -1
- package/dist/templates/claude-md.js +42 -0
- package/dist/templates/claude-md.js.map +1 -1
- package/package.json +1 -1
package/build-info.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"commitSha": "
|
|
3
|
-
"builtAt": "2026-06-
|
|
2
|
+
"commitSha": "34aff33d",
|
|
3
|
+
"builtAt": "2026-06-08T14:49:02.998Z",
|
|
4
4
|
"expectedMigrations": [
|
|
5
5
|
"20250829113330_create_org_nodes_table.sql",
|
|
6
6
|
"20250829113402_fix_function_security_search_path.sql",
|
|
@@ -19,6 +19,21 @@
|
|
|
19
19
|
* errors and git errors degrade gracefully -- they print to stderr and the
|
|
20
20
|
* command still exits 0 so the hook never blocks Claude Code.
|
|
21
21
|
*/
|
|
22
|
+
interface DaemonJsonProduct {
|
|
23
|
+
id?: string;
|
|
24
|
+
repoPath?: string;
|
|
25
|
+
}
|
|
26
|
+
interface DaemonJson {
|
|
27
|
+
teloraUrl?: string;
|
|
28
|
+
trackerId?: string;
|
|
29
|
+
productId?: string;
|
|
30
|
+
products?: DaemonJsonProduct[];
|
|
31
|
+
engines?: {
|
|
32
|
+
strategy?: {
|
|
33
|
+
integrationBranch?: string;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
}
|
|
22
37
|
interface SessionStateResponse {
|
|
23
38
|
success?: boolean;
|
|
24
39
|
connectedUrl?: string;
|
|
@@ -43,12 +58,73 @@ export interface SessionStateOptions {
|
|
|
43
58
|
config?: string;
|
|
44
59
|
}
|
|
45
60
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
61
|
+
* Three-line invariant summary. Line 1 is the connection; line 2 reminds
|
|
62
|
+
* the agent to resolve dynamic state on demand; line 3 is the load-bearing
|
|
63
|
+
* default-and-exception rule (declare intent before code). Dynamic state
|
|
64
|
+
* (active focus, branches, deliveries) is intentionally omitted -- it
|
|
65
|
+
* should be resolved on demand via MCP at the point of use, not baked into
|
|
66
|
+
* the bootstrap where it goes stale during the session. This output is
|
|
67
|
+
* injected by the SessionStart hook and is NOT wrapped in the harness's
|
|
68
|
+
* "may or may not be relevant" caveat, so it is the most reliable channel
|
|
69
|
+
* for the one invariant the agent must not reason its way around.
|
|
70
|
+
* Exported for unit testing.
|
|
50
71
|
*/
|
|
51
72
|
export declare function formatPlain(state: SessionStateResponse): string;
|
|
73
|
+
/**
|
|
74
|
+
* Resolve the default daemon.json path using global-first search order:
|
|
75
|
+
* 1. ~/.telora/daemon.json (global; written by `connect` for all current installs)
|
|
76
|
+
* 2. .telora/daemon.json in cwd (repo-local; legacy / hand-crafted)
|
|
77
|
+
*
|
|
78
|
+
* Returns the first path that exists, or null when neither does (not connected).
|
|
79
|
+
* Exported for unit testing.
|
|
80
|
+
*/
|
|
81
|
+
export declare function resolveDefaultConfigPath(): string | null;
|
|
82
|
+
/**
|
|
83
|
+
* Return the productId and repoPath for the product that owns the current cwd.
|
|
84
|
+
*
|
|
85
|
+
* In a multi-product config (e.g. Hue + Telora), the hook fetches session state
|
|
86
|
+
* for the product the session is INSIDE, not blindly for products[0]. This fixes
|
|
87
|
+
* the silent divergence where the bootstrap line reported one product while the
|
|
88
|
+
* daemon serviced another.
|
|
89
|
+
*
|
|
90
|
+
* Falls back to products[0] when no product's repoPath contains cwd (safe
|
|
91
|
+
* degradation for configs with no repoPath entries, or manual configs without a
|
|
92
|
+
* matching entry).
|
|
93
|
+
*/
|
|
94
|
+
export declare function resolveProductIdAndRepoPath(cfg: DaemonJson): {
|
|
95
|
+
productId: string | null;
|
|
96
|
+
repoPath: string;
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Pick the configured product whose repo the session is running inside.
|
|
100
|
+
*
|
|
101
|
+
* The hook calls `session-state` from the session cwd, so the cwd-matching
|
|
102
|
+
* product -- NOT blindly `products[0]` -- is the one whose CLAUDE.md should be
|
|
103
|
+
* self-healed. A repo matches when its `repoPath` equals the cwd or contains it
|
|
104
|
+
* (cwd is the repo root or a subdirectory). Returns the resolved repo path, or
|
|
105
|
+
* null when the cwd is outside every configured repo (clean no-op).
|
|
106
|
+
*/
|
|
107
|
+
export declare function resolveCwdRepoPath(cfg: DaemonJson): string | null;
|
|
108
|
+
/**
|
|
109
|
+
* Self-heal the CLAUDE.md Telora seed block for the cwd-matching product on
|
|
110
|
+
* every session open. This is the session-open analog of the daemon's
|
|
111
|
+
* boot-time `refreshClaudeMdForProducts`: a connected repo whose daemon process
|
|
112
|
+
* is not running otherwise keeps a seed frozen at connect-time, so newly
|
|
113
|
+
* shipped Telora directives never reach that workstation. The SessionStart hook
|
|
114
|
+
* runs `session-state` regardless of whether the daemon process is up, so doing
|
|
115
|
+
* the refresh here closes that gap.
|
|
116
|
+
*
|
|
117
|
+
* Reuses `writeOrMergeClaudeMd` (the same function the boot refresh uses) with
|
|
118
|
+
* productName=null -- it replaces only the delimited block, preserves all user
|
|
119
|
+
* content, and is a no-op write when the block is already current.
|
|
120
|
+
*
|
|
121
|
+
* Side-effect only: its `io.out` messages are routed to stderr so the
|
|
122
|
+
* `formatPlain` / `--json` stdout contract is byte-identical with or without a
|
|
123
|
+
* refresh. Every failure (missing file, IO/parse error, cwd outside all repos)
|
|
124
|
+
* is swallowed with a stderr note so the hook always exits 0 and session start
|
|
125
|
+
* is never blocked.
|
|
126
|
+
*/
|
|
127
|
+
export declare function selfHealClaudeMdSeed(cfg: DaemonJson): void;
|
|
52
128
|
export declare function runSessionState(opts: SessionStateOptions): Promise<void>;
|
|
53
129
|
export {};
|
|
54
130
|
//# sourceMappingURL=session-state.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-state.d.ts","sourceRoot":"","sources":["../../src/cli/session-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;
|
|
1
|
+
{"version":3,"file":"session-state.d.ts","sourceRoot":"","sources":["../../src/cli/session-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAQH,UAAU,iBAAiB;IACzB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,UAAU;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC/B,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,EAAE;YAAE,iBAAiB,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KAC3C,CAAC;CACH;AAED,UAAU,oBAAoB;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,IAAI,GAAG;QACnB,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;QACnC,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;QACrC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;KAChD,CAAC;IACF,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAQD,MAAM,WAAW,mBAAmB;IAClC,2DAA2D;IAC3D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAwGD;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,oBAAoB,GAAG,MAAM,CAS/D;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,GAAG,IAAI,CAMxD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,UAAU,GAAG;IAC5D,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAiBA;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAWjE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CAqB1D;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmC9E"}
|
|
@@ -21,7 +21,9 @@
|
|
|
21
21
|
*/
|
|
22
22
|
import { existsSync, readFileSync } from 'node:fs';
|
|
23
23
|
import { execFileSync } from 'node:child_process';
|
|
24
|
-
import {
|
|
24
|
+
import { homedir } from 'node:os';
|
|
25
|
+
import { resolve, sep } from 'node:path';
|
|
26
|
+
import { writeOrMergeClaudeMd } from './connect.js';
|
|
25
27
|
function loadDaemonJson(configPath) {
|
|
26
28
|
if (!existsSync(configPath))
|
|
27
29
|
return null;
|
|
@@ -118,10 +120,16 @@ async function callSessionState(cfg, productId) {
|
|
|
118
120
|
}
|
|
119
121
|
}
|
|
120
122
|
/**
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
123
|
+
* Three-line invariant summary. Line 1 is the connection; line 2 reminds
|
|
124
|
+
* the agent to resolve dynamic state on demand; line 3 is the load-bearing
|
|
125
|
+
* default-and-exception rule (declare intent before code). Dynamic state
|
|
126
|
+
* (active focus, branches, deliveries) is intentionally omitted -- it
|
|
127
|
+
* should be resolved on demand via MCP at the point of use, not baked into
|
|
128
|
+
* the bootstrap where it goes stale during the session. This output is
|
|
129
|
+
* injected by the SessionStart hook and is NOT wrapped in the harness's
|
|
130
|
+
* "may or may not be relevant" caveat, so it is the most reliable channel
|
|
131
|
+
* for the one invariant the agent must not reason its way around.
|
|
132
|
+
* Exported for unit testing.
|
|
125
133
|
*/
|
|
126
134
|
export function formatPlain(state) {
|
|
127
135
|
const url = state.connectedUrl ?? '';
|
|
@@ -130,26 +138,136 @@ export function formatPlain(state) {
|
|
|
130
138
|
return [
|
|
131
139
|
`Telora connected: ${url} / ${orgName} / ${productName}`,
|
|
132
140
|
'Active focuses, branches, and deliveries are resolved on demand via Telora MCP.',
|
|
141
|
+
'DEFAULT: declare intent in Telora (Focus -> delivery -> issue, moved to In Progress) BEFORE writing or scaffolding code; build directly in the working tree only when the user explicitly says so (e.g. "build locally", "just write it").',
|
|
133
142
|
].join('\n');
|
|
134
143
|
}
|
|
135
|
-
|
|
136
|
-
|
|
144
|
+
/**
|
|
145
|
+
* Resolve the default daemon.json path using global-first search order:
|
|
146
|
+
* 1. ~/.telora/daemon.json (global; written by `connect` for all current installs)
|
|
147
|
+
* 2. .telora/daemon.json in cwd (repo-local; legacy / hand-crafted)
|
|
148
|
+
*
|
|
149
|
+
* Returns the first path that exists, or null when neither does (not connected).
|
|
150
|
+
* Exported for unit testing.
|
|
151
|
+
*/
|
|
152
|
+
export function resolveDefaultConfigPath() {
|
|
153
|
+
const globalPath = resolve(homedir(), '.telora', 'daemon.json');
|
|
154
|
+
if (existsSync(globalPath))
|
|
155
|
+
return globalPath;
|
|
156
|
+
const localPath = resolve(process.cwd(), '.telora', 'daemon.json');
|
|
157
|
+
if (existsSync(localPath))
|
|
158
|
+
return localPath;
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Return the productId and repoPath for the product that owns the current cwd.
|
|
163
|
+
*
|
|
164
|
+
* In a multi-product config (e.g. Hue + Telora), the hook fetches session state
|
|
165
|
+
* for the product the session is INSIDE, not blindly for products[0]. This fixes
|
|
166
|
+
* the silent divergence where the bootstrap line reported one product while the
|
|
167
|
+
* daemon serviced another.
|
|
168
|
+
*
|
|
169
|
+
* Falls back to products[0] when no product's repoPath contains cwd (safe
|
|
170
|
+
* degradation for configs with no repoPath entries, or manual configs without a
|
|
171
|
+
* matching entry).
|
|
172
|
+
*/
|
|
173
|
+
export function resolveProductIdAndRepoPath(cfg) {
|
|
174
|
+
const cwd = resolve(process.cwd());
|
|
137
175
|
if (cfg.products && cfg.products.length > 0) {
|
|
176
|
+
// Prefer the product whose repo contains cwd (the one this session is FOR).
|
|
177
|
+
for (const product of cfg.products) {
|
|
178
|
+
if (!product.repoPath)
|
|
179
|
+
continue;
|
|
180
|
+
const repo = resolve(product.repoPath);
|
|
181
|
+
if (repo === cwd || cwd.startsWith(repo + sep)) {
|
|
182
|
+
return { productId: product.id ?? cfg.productId ?? null, repoPath: repo };
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
// No cwd match -- fall back to first product.
|
|
138
186
|
const first = cfg.products[0];
|
|
139
|
-
return {
|
|
140
|
-
productId: first.id ?? cfg.productId ?? null,
|
|
141
|
-
repoPath: first.repoPath ?? cwd,
|
|
142
|
-
};
|
|
187
|
+
return { productId: first.id ?? cfg.productId ?? null, repoPath: first.repoPath ?? cwd };
|
|
143
188
|
}
|
|
189
|
+
// Single-product legacy format.
|
|
144
190
|
return { productId: cfg.productId ?? null, repoPath: cwd };
|
|
145
191
|
}
|
|
192
|
+
/**
|
|
193
|
+
* Pick the configured product whose repo the session is running inside.
|
|
194
|
+
*
|
|
195
|
+
* The hook calls `session-state` from the session cwd, so the cwd-matching
|
|
196
|
+
* product -- NOT blindly `products[0]` -- is the one whose CLAUDE.md should be
|
|
197
|
+
* self-healed. A repo matches when its `repoPath` equals the cwd or contains it
|
|
198
|
+
* (cwd is the repo root or a subdirectory). Returns the resolved repo path, or
|
|
199
|
+
* null when the cwd is outside every configured repo (clean no-op).
|
|
200
|
+
*/
|
|
201
|
+
export function resolveCwdRepoPath(cfg) {
|
|
202
|
+
const cwd = resolve(process.cwd());
|
|
203
|
+
for (const product of cfg.products ?? []) {
|
|
204
|
+
if (!product.repoPath)
|
|
205
|
+
continue;
|
|
206
|
+
const repo = resolve(product.repoPath);
|
|
207
|
+
if (repo === cwd || cwd.startsWith(repo + sep))
|
|
208
|
+
return repo;
|
|
209
|
+
}
|
|
210
|
+
// Single-product legacy format: productId without a products array.
|
|
211
|
+
// The hook runs from the repo root, so cwd is the repo path.
|
|
212
|
+
if (!cfg.products?.length && cfg.productId)
|
|
213
|
+
return cwd;
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Self-heal the CLAUDE.md Telora seed block for the cwd-matching product on
|
|
218
|
+
* every session open. This is the session-open analog of the daemon's
|
|
219
|
+
* boot-time `refreshClaudeMdForProducts`: a connected repo whose daemon process
|
|
220
|
+
* is not running otherwise keeps a seed frozen at connect-time, so newly
|
|
221
|
+
* shipped Telora directives never reach that workstation. The SessionStart hook
|
|
222
|
+
* runs `session-state` regardless of whether the daemon process is up, so doing
|
|
223
|
+
* the refresh here closes that gap.
|
|
224
|
+
*
|
|
225
|
+
* Reuses `writeOrMergeClaudeMd` (the same function the boot refresh uses) with
|
|
226
|
+
* productName=null -- it replaces only the delimited block, preserves all user
|
|
227
|
+
* content, and is a no-op write when the block is already current.
|
|
228
|
+
*
|
|
229
|
+
* Side-effect only: its `io.out` messages are routed to stderr so the
|
|
230
|
+
* `formatPlain` / `--json` stdout contract is byte-identical with or without a
|
|
231
|
+
* refresh. Every failure (missing file, IO/parse error, cwd outside all repos)
|
|
232
|
+
* is swallowed with a stderr note so the hook always exits 0 and session start
|
|
233
|
+
* is never blocked.
|
|
234
|
+
*/
|
|
235
|
+
export function selfHealClaudeMdSeed(cfg) {
|
|
236
|
+
try {
|
|
237
|
+
const repoPath = resolveCwdRepoPath(cfg);
|
|
238
|
+
if (!repoPath)
|
|
239
|
+
return; // cwd is not a configured product repo -- clean no-op.
|
|
240
|
+
// Only REFRESH an existing CLAUDE.md; creation is `connect`'s job. A
|
|
241
|
+
// connected repo always has one, so a missing file is treated as a safe
|
|
242
|
+
// no-op rather than silently spawning a CLAUDE.md from a session hook.
|
|
243
|
+
if (!existsSync(resolve(repoPath, 'CLAUDE.md')))
|
|
244
|
+
return;
|
|
245
|
+
const io = {
|
|
246
|
+
// Route stdout-bound notes to stderr: the refresh must not perturb the
|
|
247
|
+
// plain/json payload the hook consumes from stdout.
|
|
248
|
+
out: (msg) => process.stderr.write(msg),
|
|
249
|
+
err: (msg) => process.stderr.write(msg),
|
|
250
|
+
fetch: globalThis.fetch,
|
|
251
|
+
};
|
|
252
|
+
writeOrMergeClaudeMd(repoPath, null, io);
|
|
253
|
+
}
|
|
254
|
+
catch (err) {
|
|
255
|
+
process.stderr.write(`session-state: CLAUDE.md seed refresh skipped: ${err.message}\n`);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
146
258
|
export async function runSessionState(opts) {
|
|
147
|
-
const configPath = resolve(opts.config
|
|
259
|
+
const configPath = opts.config ? resolve(opts.config) : resolveDefaultConfigPath();
|
|
260
|
+
if (!configPath)
|
|
261
|
+
return; // Not Telora-connected -- silent success.
|
|
148
262
|
const cfg = loadDaemonJson(configPath);
|
|
149
263
|
if (!cfg) {
|
|
150
264
|
// Not Telora-connected -- silent success.
|
|
151
265
|
return;
|
|
152
266
|
}
|
|
267
|
+
// Self-heal the CLAUDE.md seed before anything else so it runs on BOTH the
|
|
268
|
+
// plain and --json paths and regardless of whether the network call below
|
|
269
|
+
// succeeds. Local fs only; no network; degrade-safe.
|
|
270
|
+
selfHealClaudeMdSeed(cfg);
|
|
153
271
|
const { productId, repoPath } = resolveProductIdAndRepoPath(cfg);
|
|
154
272
|
if (!productId) {
|
|
155
273
|
process.stderr.write('session-state: daemon.json has no productId\n');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-state.js","sourceRoot":"","sources":["../../src/cli/session-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"session-state.js","sourceRoot":"","sources":["../../src/cli/session-state.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-md.d.ts","sourceRoot":"","sources":["../../src/templates/claude-md.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,eAAO,MAAM,sBAAsB,+BAA+B,CAAC;AACnE,eAAO,MAAM,oBAAoB,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"claude-md.d.ts","sourceRoot":"","sources":["../../src/templates/claude-md.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,eAAO,MAAM,sBAAsB,+BAA+B,CAAC;AACnE,eAAO,MAAM,oBAAoB,6BAA6B,CAAC;AA8J/D;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CASjE"}
|
|
@@ -19,6 +19,48 @@ This repo is connected to Telora -- a differential control plane for
|
|
|
19
19
|
software delivery. Intent and reality are paired signals; the meaningful
|
|
20
20
|
work happens at the difference.
|
|
21
21
|
|
|
22
|
+
## Before you write any code (read this first)
|
|
23
|
+
|
|
24
|
+
DEFAULT: on a Telora-connected workstation, a new capability starts as
|
|
25
|
+
**declared intent** before any code. When the user says "I want to build
|
|
26
|
+
X", your first move is NOT to scaffold X -- it is to declare it: create
|
|
27
|
+
(or select) a Focus -> delivery -> issue and move an issue to **In
|
|
28
|
+
Progress**. Code is written only after intent is anchored above it.
|
|
29
|
+
|
|
30
|
+
This polarity is deliberate and easy to get backwards. Building directly
|
|
31
|
+
in the working tree -- scaffolding, installing dependencies, starting a
|
|
32
|
+
dev server, writing application files -- is the **exception**, taken ONLY
|
|
33
|
+
when the user explicitly asks for it. Recognized bypass phrases:
|
|
34
|
+
"build locally", "just write it", "skip Telora", "don't track this",
|
|
35
|
+
"throwaway". Absent an explicit signal like these, treat any build
|
|
36
|
+
request as a request to declare intent in Telora first.
|
|
37
|
+
|
|
38
|
+
Asking good clarifying questions about stack, scope, or dependencies is
|
|
39
|
+
NOT a substitute for this step -- that is execution-layer scoping, and it
|
|
40
|
+
comes *after* the capability is declared, not instead of it. Scoping is
|
|
41
|
+
agent work; declaring that a capability matters is the part that must
|
|
42
|
+
land in Telora first.
|
|
43
|
+
|
|
44
|
+
**Surface the fork; do not silently pick it.** The common failure is
|
|
45
|
+
resolving an ambiguous request toward the path of least resistance --
|
|
46
|
+
e.g. reading "a web app I run locally on my LAN" (a deployment target) as
|
|
47
|
+
"build locally" (skip Telora). When intent is not already explicit, your
|
|
48
|
+
FIRST response to a build request names the choice rather than assuming
|
|
49
|
+
it: "I'll scope this in Telora unless you want it built locally -- which?"
|
|
50
|
+
One question, once, at the start. Let the user pick; never pick for them
|
|
51
|
+
by starting to type code.
|
|
52
|
+
|
|
53
|
+
**First action rule.** On a build / new-capability request, your first
|
|
54
|
+
tool call is a Telora planning call (telora_product_focus / _delivery /
|
|
55
|
+
_issue) OR the fork question above -- never Write, Edit, or a code-running
|
|
56
|
+
Bash command. If the first move cannot be code, building-before-intent
|
|
57
|
+
cannot happen.
|
|
58
|
+
|
|
59
|
+
Why: an artifact with no declared intent above it is reality moving with
|
|
60
|
+
nothing to measure it against -- pure noise to the differential loop. The
|
|
61
|
+
whole system is built to compute intent-minus-reality; code that skips
|
|
62
|
+
the intent half defeats the instrument.
|
|
63
|
+
|
|
22
64
|
## Planning hierarchy
|
|
23
65
|
|
|
24
66
|
- **Focus** = one capability. All phases of building one thing belong
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-md.js","sourceRoot":"","sources":["../../src/templates/claude-md.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,CAAC,MAAM,sBAAsB,GAAG,4BAA4B,CAAC;AACnE,MAAM,CAAC,MAAM,oBAAoB,GAAG,0BAA0B,CAAC;AAE/D,MAAM,SAAS,GAAG
|
|
1
|
+
{"version":3,"file":"claude-md.js","sourceRoot":"","sources":["../../src/templates/claude-md.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,CAAC,MAAM,sBAAsB,GAAG,4BAA4B,CAAC;AACnE,MAAM,CAAC,MAAM,oBAAoB,GAAG,0BAA0B,CAAC;AAE/D,MAAM,SAAS,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0JjB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,WAA0B;IACvD,MAAM,WAAW,GAAG,WAAW;QAC7B,CAAC,CAAC,kCAAkC,WAAW,SAAS;QACxD,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,KAAK,GACT,GAAG,sBAAsB,IAAI;QAC7B,GAAG,WAAW,GAAG,SAAS,EAAE;QAC5B,GAAG,oBAAoB,IAAI,CAAC;IAC9B,OAAO,KAAK,CAAC;AACf,CAAC"}
|