autodev-cli 1.4.86 → 1.4.94

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/media/profile/00-identity.md +35 -0
  2. package/media/profile/01-learning.md +23 -0
  3. package/media/profile/02-memory-mcp.md +49 -0
  4. package/media/profile/03-living-docs.md +18 -0
  5. package/media/profile/04-skill-files.md +9 -0
  6. package/media/profile/05-skill-creation.md +18 -0
  7. package/media/profile/06-core-rules.md +58 -0
  8. package/media/profile/07-core-loop.md +31 -0
  9. package/media/profile/08-thinking.md +30 -0
  10. package/media/profile/09-parallel-panel.md +29 -0
  11. package/media/profile/10-codebase-verification.md +19 -0
  12. package/media/profile/11-git-debug-security.md +16 -0
  13. package/media/profile/12-todo-format.md +20 -0
  14. package/media/profile/13-workflow-principles.md +17 -0
  15. package/media/profile/14-contracts.md +16 -0
  16. package/media/profile/15-soul.md +12 -0
  17. package/media/profile/16-journal.md +38 -0
  18. package/media/profile/17-issue-tracking.md +19 -0
  19. package/media/profile/18-knowledgebase.md +13 -0
  20. package/media/profile/19-subagent-context-management.md +510 -0
  21. package/media/profile/20-project-graph.md +56 -0
  22. package/out/agentBackup/layout.js +1 -0
  23. package/out/agentBackup/layout.js.map +1 -1
  24. package/out/commands/mcpOperate.js +544 -28
  25. package/out/commands/mcpOperate.js.map +1 -1
  26. package/out/configManager.d.ts +7 -0
  27. package/out/configManager.js +36 -0
  28. package/out/configManager.js.map +1 -1
  29. package/out/core/modelInfo.d.ts +28 -0
  30. package/out/core/modelInfo.js +97 -0
  31. package/out/core/modelInfo.js.map +1 -0
  32. package/out/core/projectSkills.d.ts +44 -0
  33. package/out/core/projectSkills.js +266 -0
  34. package/out/core/projectSkills.js.map +1 -0
  35. package/out/core/redactSecrets.d.ts +15 -0
  36. package/out/core/redactSecrets.js +110 -0
  37. package/out/core/redactSecrets.js.map +1 -0
  38. package/out/core/settingsLoader.d.ts +13 -1
  39. package/out/core/settingsLoader.js +1 -0
  40. package/out/core/settingsLoader.js.map +1 -1
  41. package/out/graphStore.d.ts +153 -0
  42. package/out/graphStore.js +412 -0
  43. package/out/graphStore.js.map +1 -0
  44. package/out/mcpInstallCheck.d.ts +2 -1
  45. package/out/mcpInstallCheck.js.map +1 -1
  46. package/out/profileBuilder.js +26 -1
  47. package/out/profileBuilder.js.map +1 -1
  48. package/out/taskLoop.d.ts +8 -0
  49. package/out/taskLoop.js +55 -2
  50. package/out/taskLoop.js.map +1 -1
  51. package/out/webSocketPoller.d.ts +3 -0
  52. package/out/webSocketPoller.js +11 -0
  53. package/out/webSocketPoller.js.map +1 -1
  54. package/out/webhookPoller.d.ts +1 -0
  55. package/out/webhookPoller.js +5 -0
  56. package/out/webhookPoller.js.map +1 -1
  57. package/package.json +4 -3
@@ -0,0 +1,266 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.providerConsumesSkills = providerConsumesSkills;
37
+ exports.sanitizeRemoteSkills = sanitizeRemoteSkills;
38
+ exports.saveProjectSkills = saveProjectSkills;
39
+ exports.foldSkillsIntoProfile = foldSkillsIntoProfile;
40
+ const fs = __importStar(require("fs"));
41
+ const path = __importStar(require("path"));
42
+ const pathSafe_1 = require("./pathSafe");
43
+ // A skill slug is a plain directory name: lowercase alnum + hyphen only. No
44
+ // separators, no dots — this alone rejects "../evil", "a/b", ".hidden", etc.
45
+ const SKILL_NAME_RE = /^[a-z0-9][a-z0-9-]*$/;
46
+ // Caps — the whole point of the sanitizer. Keep them strict.
47
+ const MAX_SKILLS = 100; // total number of skills per sync
48
+ const MAX_NAME_LEN = 64; // slug length
49
+ const MAX_DESC_BYTES = 4 * 1024; // 4 KB per description
50
+ const MAX_BODY_BYTES = 64 * 1024; // 64 KB per body
51
+ const MAX_TOTAL_BYTES = 4 * 1024 * 1024; // 4 MB across all skills
52
+ const SKILLS_REL_DIR = path.posix.join('.claude', 'skills');
53
+ const MANIFEST_REL = path.join('.autodev', 'synced-skills.json');
54
+ /** True for providers that natively load `.claude/skills/<slug>/SKILL.md` (Claude only). */
55
+ function providerConsumesSkills(provider) {
56
+ return provider === 'claude-cli' || provider === 'claude-tui';
57
+ }
58
+ /**
59
+ * Validate an untrusted `skills` array (from a `skill_update` frame) down to the
60
+ * subset that is safe to write. Enforces slug shape, string types, per-file and
61
+ * aggregate size caps, a total count cap, and workspace path containment.
62
+ * Returns the accepted list (in order) plus the rejected entries with reasons.
63
+ * Callers must still gate the whole path behind an opt-in (skillUpdateEnabled).
64
+ */
65
+ function sanitizeRemoteSkills(root, skills) {
66
+ const safe = [];
67
+ const rejected = [];
68
+ if (!Array.isArray(skills)) {
69
+ return { safe, rejected };
70
+ }
71
+ const seen = new Set();
72
+ let totalBytes = 0;
73
+ for (const raw of skills) {
74
+ const entry = raw;
75
+ const rawName = typeof entry?.name === 'string' ? entry.name.trim() : '';
76
+ const label = rawName || '(unnamed)';
77
+ if (!entry || typeof entry !== 'object') {
78
+ rejected.push({ name: label, reason: 'not an object' });
79
+ continue;
80
+ }
81
+ if (!SKILL_NAME_RE.test(rawName)) {
82
+ rejected.push({ name: label, reason: 'invalid slug (must match ^[a-z0-9][a-z0-9-]*$)' });
83
+ continue;
84
+ }
85
+ if (rawName.length > MAX_NAME_LEN) {
86
+ rejected.push({ name: label, reason: 'slug too long' });
87
+ continue;
88
+ }
89
+ if (seen.has(rawName)) {
90
+ rejected.push({ name: rawName, reason: 'duplicate slug' });
91
+ continue;
92
+ }
93
+ if (typeof entry.description !== 'string') {
94
+ rejected.push({ name: rawName, reason: 'description not a string' });
95
+ continue;
96
+ }
97
+ if (typeof entry.body !== 'string') {
98
+ rejected.push({ name: rawName, reason: 'body not a string' });
99
+ continue;
100
+ }
101
+ const descBytes = Buffer.byteLength(entry.description, 'utf8');
102
+ const bodyBytes = Buffer.byteLength(entry.body, 'utf8');
103
+ if (descBytes > MAX_DESC_BYTES) {
104
+ rejected.push({ name: rawName, reason: `description too large (${descBytes} > ${MAX_DESC_BYTES})` });
105
+ continue;
106
+ }
107
+ if (bodyBytes > MAX_BODY_BYTES) {
108
+ rejected.push({ name: rawName, reason: `body too large (${bodyBytes} > ${MAX_BODY_BYTES})` });
109
+ continue;
110
+ }
111
+ // Path-safety: the composed target must resolve INSIDE the workspace, even
112
+ // after symlink resolution. (The slug regex already blocks ../ and /, this
113
+ // is belt-and-suspenders + symlink defence.)
114
+ const target = (0, pathSafe_1.resolveWithinRoot)(root, path.posix.join(SKILLS_REL_DIR, rawName, 'SKILL.md'), false);
115
+ if (!target) {
116
+ rejected.push({ name: rawName, reason: 'path escapes workspace' });
117
+ continue;
118
+ }
119
+ if (safe.length >= MAX_SKILLS) {
120
+ rejected.push({ name: rawName, reason: `over skill count cap (${MAX_SKILLS})` });
121
+ continue;
122
+ }
123
+ if (totalBytes + descBytes + bodyBytes > MAX_TOTAL_BYTES) {
124
+ rejected.push({ name: rawName, reason: `over total bytes cap (${MAX_TOTAL_BYTES})` });
125
+ continue;
126
+ }
127
+ totalBytes += descBytes + bodyBytes;
128
+ seen.add(rawName);
129
+ safe.push({ name: rawName, description: entry.description, body: entry.body });
130
+ }
131
+ return { safe, rejected };
132
+ }
133
+ /** Compose the on-disk SKILL.md (frontmatter + body). Description newlines are
134
+ * collapsed to keep the YAML frontmatter valid. */
135
+ function _composeSkillFile(s) {
136
+ const desc = s.description.replace(/[\r\n]+/g, ' ').trim();
137
+ const body = s.body.replace(/\s+$/, '');
138
+ return `---\nname: ${s.name}\ndescription: ${desc}\n---\n\n${body}\n`;
139
+ }
140
+ function _readManifest(root) {
141
+ try {
142
+ const f = path.join(root, MANIFEST_REL);
143
+ if (!fs.existsSync(f)) {
144
+ return [];
145
+ }
146
+ const arr = JSON.parse(fs.readFileSync(f, 'utf8'));
147
+ return Array.isArray(arr) ? arr.filter((x) => typeof x === 'string') : [];
148
+ }
149
+ catch {
150
+ return [];
151
+ }
152
+ }
153
+ function _writeManifest(root, slugs) {
154
+ const f = path.join(root, MANIFEST_REL);
155
+ const dir = path.dirname(f);
156
+ if (!fs.existsSync(dir)) {
157
+ fs.mkdirSync(dir, { recursive: true });
158
+ }
159
+ fs.writeFileSync(f, JSON.stringify(slugs, null, 2) + '\n', 'utf8');
160
+ }
161
+ /**
162
+ * Write the supplied (already-sanitized) skills to `<root>/.claude/skills/<slug>/SKILL.md`
163
+ * as a FULL REPLACE: every previously-synced skill (tracked in the manifest) that
164
+ * is NOT in the new set is removed, and its now-empty dir pruned. Skills we did
165
+ * not write (CLI-bundled via applyAllSkills, or user hand-made) are never touched.
166
+ * Returns the slugs written and removed.
167
+ */
168
+ function saveProjectSkills(root, safeSkills) {
169
+ const prev = _readManifest(root);
170
+ const nextSet = new Set(safeSkills.map(s => s.name));
171
+ const written = [];
172
+ const removed = [];
173
+ // Write / overwrite each safe skill.
174
+ for (const s of safeSkills) {
175
+ const target = (0, pathSafe_1.resolveWithinRoot)(root, path.posix.join(SKILLS_REL_DIR, s.name, 'SKILL.md'), false);
176
+ if (!target) {
177
+ continue;
178
+ } // defensive — sanitizer already validated
179
+ try {
180
+ const dir = path.dirname(target);
181
+ if (!fs.existsSync(dir)) {
182
+ fs.mkdirSync(dir, { recursive: true });
183
+ }
184
+ fs.writeFileSync(target, _composeSkillFile(s), 'utf8');
185
+ written.push(s.name);
186
+ }
187
+ catch { /* ignore individual write errors */ }
188
+ }
189
+ // Remove previously-synced skills that are gone from the new set — but ONLY
190
+ // ones we own (in the manifest), never bundled or hand-made skills.
191
+ for (const slug of prev) {
192
+ if (nextSet.has(slug)) {
193
+ continue;
194
+ }
195
+ if (!SKILL_NAME_RE.test(slug)) {
196
+ continue;
197
+ } // defensive
198
+ const target = (0, pathSafe_1.resolveWithinRoot)(root, path.posix.join(SKILLS_REL_DIR, slug, 'SKILL.md'), false);
199
+ if (!target) {
200
+ continue;
201
+ }
202
+ try {
203
+ if (fs.existsSync(target)) {
204
+ fs.unlinkSync(target);
205
+ }
206
+ const dir = path.dirname(target);
207
+ if (fs.existsSync(dir) && fs.readdirSync(dir).length === 0) {
208
+ fs.rmdirSync(dir);
209
+ }
210
+ removed.push(slug);
211
+ }
212
+ catch { /* ignore */ }
213
+ }
214
+ _writeManifest(root, written);
215
+ return { written, removed };
216
+ }
217
+ // ---------------------------------------------------------------------------
218
+ // Prose fold — for non-Claude providers (opencode/grok/copilot) that cannot
219
+ // load SKILL.md, fold a short managed "## Skills" section into AGENTS.md so
220
+ // those agents still benefit. Idempotent: replaces a marker block, never
221
+ // appends forever. Passing an empty list removes the block.
222
+ // ---------------------------------------------------------------------------
223
+ const SKILLS_FOLD_BEGIN = '<!-- autodev:skills:begin -->';
224
+ const SKILLS_FOLD_END = '<!-- autodev:skills:end -->';
225
+ const SKILLS_FOLD_RE = /\n*<!-- autodev:skills:begin -->[\s\S]*?<!-- autodev:skills:end -->\n*/;
226
+ /**
227
+ * Fold the given skills into a managed "## Skills" block in `<root>/AGENTS.md`
228
+ * (best-effort, idempotent). Non-Claude agents read AGENTS.md but cannot load
229
+ * `.claude/skills`, so this is how they gain the skill instructions. An empty
230
+ * list strips the block.
231
+ */
232
+ function foldSkillsIntoProfile(root, safeSkills) {
233
+ if (!root) {
234
+ return;
235
+ }
236
+ const target = path.join(root, 'AGENTS.md');
237
+ let block = '';
238
+ if (safeSkills.length > 0) {
239
+ const parts = safeSkills.map(s => {
240
+ const desc = s.description.replace(/[\r\n]+/g, ' ').trim();
241
+ return `### ${s.name}\n\n${desc}\n\n${s.body.trim()}`;
242
+ });
243
+ block = `${SKILLS_FOLD_BEGIN}\n\n## Skills\n\n${parts.join('\n\n')}\n\n${SKILLS_FOLD_END}`;
244
+ }
245
+ let content = '';
246
+ try {
247
+ if (fs.existsSync(target)) {
248
+ content = fs.readFileSync(target, 'utf8');
249
+ }
250
+ }
251
+ catch { /* treat as empty */ }
252
+ if (SKILLS_FOLD_RE.test(content)) {
253
+ content = content.replace(SKILLS_FOLD_RE, block ? `\n\n${block}\n` : '\n');
254
+ }
255
+ else if (block) {
256
+ content = content ? `${content.replace(/\s+$/, '')}\n\n${block}\n` : `${block}\n`;
257
+ }
258
+ else {
259
+ return; // nothing to add, nothing to strip
260
+ }
261
+ try {
262
+ fs.writeFileSync(target, content, 'utf8');
263
+ }
264
+ catch { /* best-effort */ }
265
+ }
266
+ //# sourceMappingURL=projectSkills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projectSkills.js","sourceRoot":"","sources":["../../src/core/projectSkills.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Redact known secret shapes from a single string. Applies every pattern in
3
+ * order (specific before generic). Returns the string unchanged when it holds
4
+ * no secrets. Safe on empty / non-secret prose.
5
+ */
6
+ export declare function redactSecrets(text: string): string;
7
+ /**
8
+ * Deep-redact every STRING value inside an object/array, leaving structure and
9
+ * KEYS intact. Hook events forwarded to the office are objects (not flat
10
+ * strings) — their tool_input.command, tool_response, message text, etc. can
11
+ * each carry a secret — so we walk the whole value and run `redactSecrets` on
12
+ * every string leaf. Non-string leaves (numbers, booleans, null) pass through
13
+ * untouched. Returns a NEW value; the input is not mutated.
14
+ */
15
+ export declare function redactDeep<T>(value: T): T;
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ // Secrets anonymizer for OUTBOUND agent content.
3
+ //
4
+ // Agent-originated content (tool calls/output, bash output, file reads,
5
+ // assistant prose) is forwarded from the CLI to the pixel-office, where it is
6
+ // STORED and DISPLAYED in the office feed/chat. Secrets (API keys, tokens) can
7
+ // leak into that stream. We redact them HERE, before the content leaves the
8
+ // machine — mirroring how the tutor project redacts its trace files.
9
+ //
10
+ // Scope: this is applied ONLY to outbound content going to the office (hook
11
+ // events, assistant narration, autonomy task results / A2A replies). It is NOT
12
+ // applied to the model's actual input, local files on disk, or the api_key used
13
+ // for auth (that travels as an HTTP header, not as content).
14
+ //
15
+ // Performance: the pattern list is compiled ONCE at module load (the const
16
+ // array below) and reused for every call. `redactSecrets` runs on every
17
+ // forwarded event, so we never rebuild RegExp objects per-call.
18
+ //
19
+ // Ordering: patterns run in array order — SPECIFIC shapes before GENERIC ones
20
+ // (e.g. `sk-ant-` before the generic `sk-` key, so an Anthropic key is labelled
21
+ // as such and its remainder can't be re-matched by a broader rule).
22
+ //
23
+ // The min-length bounds in each pattern are deliberate: they stop the generic
24
+ // rules from mangling ordinary prose. Do NOT loosen them.
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.redactSecrets = redactSecrets;
27
+ exports.redactDeep = redactDeep;
28
+ // NOTE on emails: the reference trace-redactor also maps plain email addresses
29
+ // (PII). We DELIBERATELY do NOT redact emails here — user emails legitimately
30
+ // appear in the office UI (character owners, teammates), and redacting them
31
+ // would mangle normal content. So no email pattern is included.
32
+ const PATTERNS = [
33
+ // Anthropic API keys — must run BEFORE the generic `sk-` rule.
34
+ { name: 'anthropic_key', re: /sk-ant-[A-Za-z0-9_-]{15,}/g, replacement: 'sk-ant-REDACTED' },
35
+ // Generic OpenAI-style `sk-…` keys.
36
+ { name: 'openai_style_key', re: /sk-[A-Za-z0-9]{20,}/g, replacement: 'sk-REDACTED' },
37
+ // GitHub tokens: gho_/ghp_/ghr_/ghs_/ghu_.
38
+ { name: 'gh_token', re: /gh[oprsu]_[A-Za-z0-9]{20,}/g, replacement: 'gh_REDACTED' },
39
+ // GitHub fine-grained PATs.
40
+ { name: 'gh_pat', re: /github_pat_[A-Za-z0-9_]{20,}/g, replacement: 'github_pat_REDACTED' },
41
+ // Google API keys.
42
+ { name: 'google_api_key', re: /AIza[0-9A-Za-z_-]{25,}/g, replacement: 'AIza_REDACTED' },
43
+ // Slack tokens: xoxb/xoxa/xoxp/xoxr/xoxs.
44
+ { name: 'slack_token', re: /xox[baprs]-[0-9A-Za-z-]{20,}/g, replacement: 'xoxX-REDACTED' },
45
+ // AWS access key IDs.
46
+ { name: 'aws_access_key', re: /AKIA[0-9A-Z]{16}/g, replacement: 'AKIA_REDACTED' },
47
+ // Stripe secret/publishable/restricted live+test keys.
48
+ { name: 'stripe_key', re: /(?:sk|pk|rk)_(?:live|test)_[0-9A-Za-z]{20,}/g, replacement: 'stripe_REDACTED' },
49
+ // JWTs (three base64url segments).
50
+ { name: 'jwt_token', re: /eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g, replacement: 'eyJ.REDACTED.JWT' },
51
+ // `Bearer <token>` — keep the "Bearer " prefix, redact the credential.
52
+ { name: 'bearer_token', re: /([Bb]earer\s+)[A-Za-z0-9._~+/=-]{20,}/g, replacement: '$1REDACTED_BEARER' },
53
+ // PEM private-key blocks (RSA / EC / OPENSSH / generic).
54
+ { name: 'private_key', re: /-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z0-9 ]*PRIVATE KEY-----/g, replacement: '-----REDACTED_PRIVATE_KEY-----' },
55
+ // JSON `"password": "…"` values.
56
+ { name: 'password_json', re: /("[Pp]ass(?:word|wd)"\s*:\s*")[^"\\]+(")/g, replacement: '$1REDACTED$2' },
57
+ // JSON `"token"/"auth_token"/"api_token"` values.
58
+ { name: 'token_json', re: /("(?:[Aa]uth|[Aa]pi)?_?[Tt]oken"\s*:\s*")[^"\\]{15,}(")/g, replacement: '$1REDACTED$2' },
59
+ // Shell/env `FOO_TOKEN=…`, `API_KEY: …`, `*_SECRET=…`, `*_PASSWORD=…`.
60
+ { name: 'env_var_secret', re: /([A-Z][A-Z0-9_]*(?:TOKEN|SECRET|API[_-]?KEY|PASSWORD|PASSWD)[A-Z0-9_]*\s*[:=]\s*["']?)[A-Za-z0-9/_+.=-]{15,}/g, replacement: '$1REDACTED' },
61
+ // ── Our own pixel-office agent credential shapes ────────────────────────────
62
+ // These are the office agent api_keys (`agt_…`) and personal access tokens
63
+ // (`pat_…`). They authenticate a character to the office and must NEVER show
64
+ // up in the office feed itself.
65
+ { name: 'agt_key', re: /agt_[A-Za-z0-9]{16,}/g, replacement: 'agt_REDACTED' },
66
+ { name: 'pat_key', re: /pat_[A-Za-z0-9]{16,}/g, replacement: 'pat_REDACTED' },
67
+ ];
68
+ /**
69
+ * Redact known secret shapes from a single string. Applies every pattern in
70
+ * order (specific before generic). Returns the string unchanged when it holds
71
+ * no secrets. Safe on empty / non-secret prose.
72
+ */
73
+ function redactSecrets(text) {
74
+ if (!text) {
75
+ return text;
76
+ }
77
+ let out = text;
78
+ for (const p of PATTERNS) {
79
+ // `re` is a shared module-level RegExp with the global flag. String.replace
80
+ // does not rely on / advance its lastIndex, so reuse is safe and allocation-
81
+ // free (unlike RegExp.exec, which would need a lastIndex reset).
82
+ out = out.replace(p.re, p.replacement);
83
+ }
84
+ return out;
85
+ }
86
+ /**
87
+ * Deep-redact every STRING value inside an object/array, leaving structure and
88
+ * KEYS intact. Hook events forwarded to the office are objects (not flat
89
+ * strings) — their tool_input.command, tool_response, message text, etc. can
90
+ * each carry a secret — so we walk the whole value and run `redactSecrets` on
91
+ * every string leaf. Non-string leaves (numbers, booleans, null) pass through
92
+ * untouched. Returns a NEW value; the input is not mutated.
93
+ */
94
+ function redactDeep(value) {
95
+ if (typeof value === 'string') {
96
+ return redactSecrets(value);
97
+ }
98
+ if (Array.isArray(value)) {
99
+ return value.map((v) => redactDeep(v));
100
+ }
101
+ if (value && typeof value === 'object') {
102
+ const out = {};
103
+ for (const [k, v] of Object.entries(value)) {
104
+ out[k] = redactDeep(v);
105
+ }
106
+ return out;
107
+ }
108
+ return value;
109
+ }
110
+ //# sourceMappingURL=redactSecrets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redactSecrets.js","sourceRoot":"","sources":["../../src/core/redactSecrets.ts"],"names":[],"mappings":"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"}
@@ -40,6 +40,15 @@ export interface AutodevSettings {
40
40
  * enableFileBrowser / gitEnabled). Even when enabled, entries are validated.
41
41
  */
42
42
  mcpUpdateEnabled: boolean;
43
+ /**
44
+ * Opt-in: honor `skill_update` frames pushed over the WS channel. When false
45
+ * (default), inbound skill_update frames are ignored. Writing remote-supplied
46
+ * skills drops instruction files into `.claude/skills/` that a running Claude
47
+ * agent live-reads, so it is an instruction-injection surface and must be
48
+ * explicitly enabled (mirrors mcpUpdateEnabled). Even when enabled, each skill
49
+ * is validated (slug shape, size caps, workspace path containment).
50
+ */
51
+ skillUpdateEnabled: boolean;
43
52
  hooksEnabled: boolean;
44
53
  hooksScope: 'project' | 'global';
45
54
  openCodeHooksEnabled: boolean;
@@ -94,10 +103,13 @@ export interface AutodevSettings {
94
103
  * opencode.json, .vscode/mcp.json) alongside the autodev defaults.
95
104
  */
96
105
  mcpServers: Record<string, {
97
- command: string;
106
+ command?: string;
98
107
  args?: string[];
99
108
  env?: Record<string, string>;
100
109
  enabled?: boolean;
110
+ type?: 'stdio' | 'http' | 'sse';
111
+ url?: string;
112
+ headers?: Record<string, string>;
101
113
  }>;
102
114
  /**
103
115
  * Names of built-in MCP servers (from DEFAULT_MCP_SERVERS) that the user
@@ -71,6 +71,7 @@ exports.SETTINGS_DEFAULTS = {
71
71
  enableFileBrowser: false,
72
72
  gitEnabled: false,
73
73
  mcpUpdateEnabled: false,
74
+ skillUpdateEnabled: false,
74
75
  hooksEnabled: false,
75
76
  hooksScope: 'project',
76
77
  openCodeHooksEnabled: false,
@@ -1 +1 @@
1
- {"version":3,"file":"settingsLoader.js","sourceRoot":"","sources":["../../src/core/settingsLoader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"settingsLoader.js","sourceRoot":"","sources":["../../src/core/settingsLoader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Project Graph — durable, per-project, cross-session shared memory for agents.
3
+ *
4
+ * This is the "knowledge/work graph" from the graph-engineering playbook: a
5
+ * typed, queryable graph of Entities, Claims, Sources, Artifacts, AgentRuns,
6
+ * Evaluations, Tasks, Commits and Metrics, connected by provenance edges. It is
7
+ * DISTINCT from the file-based memory (`.autodev/memories/`) and the Memory MCP:
8
+ * memory is prose recall; the graph is structured, sourced, versioned facts that
9
+ * many agents read and write across sessions. The mantra: the agent forgets, the
10
+ * graph does not.
11
+ *
12
+ * STORAGE. One append-only log per project at `.autodev/graph/graph.jsonl`.
13
+ * Every mutation is a self-contained JSON line carrying its own provenance
14
+ * (run_id, agent_id, timestamp). Current state is materialised by replaying the
15
+ * log. Append-only buys three things the playbook demands: an audit trail,
16
+ * crash safety, and lock-free concurrent writes — several agents in the same
17
+ * workspace simply append their own lines and re-read to see each other's.
18
+ *
19
+ * INVARIANTS (enforced on write, per the playbook):
20
+ * 1. Every `claim` has a source, or is explicitly marked `inference: true`.
21
+ * 2. Every `artifact` has an authoring run (auto) and a `version`.
22
+ * 3. Every `evaluation` identifies a `rubric`.
23
+ * 4. Superseded nodes remain addressable — supersede never deletes; it links a
24
+ * new version with a `supersedes` edge and flags the old one.
25
+ */
26
+ export type GraphNodeType = 'entity' | 'claim' | 'source' | 'artifact' | 'agent_run' | 'evaluation' | 'task' | 'commit' | 'metric' | 'note' | 'question' | 'decision';
27
+ export type GraphEdgeType = 'mentions' | 'supports' | 'contradicts' | 'derived_from' | 'produced' | 'evaluates' | 'revises' | 'supersedes' | 'depends_on' | 'parent_of' | 'resolved_to' | 'relates_to';
28
+ export declare const NODE_TYPES: GraphNodeType[];
29
+ export declare const EDGE_TYPES: GraphEdgeType[];
30
+ export interface GraphNode {
31
+ id: string;
32
+ type: GraphNodeType;
33
+ name: string;
34
+ body?: string;
35
+ props?: Record<string, unknown>;
36
+ /** Where the fact came from (a citation, url, file:line, or a source node id). */
37
+ source?: string;
38
+ /** Claims only: true when the claim is a reasoned inference, not sourced. */
39
+ inference?: boolean;
40
+ /** Artifacts only: the version this node describes. */
41
+ version?: string;
42
+ /** Evaluations only: the rubric the judgement was made against. */
43
+ rubric?: string;
44
+ aliases?: string[];
45
+ /** Set when a newer node supersedes this one; the node stays addressable. */
46
+ supersededBy?: string;
47
+ runId: string;
48
+ agentId: string;
49
+ createdAt: string;
50
+ updatedAt: string;
51
+ }
52
+ export interface GraphEdge {
53
+ id: string;
54
+ type: GraphEdgeType;
55
+ from: string;
56
+ to: string;
57
+ props?: Record<string, unknown>;
58
+ source?: string;
59
+ runId: string;
60
+ agentId: string;
61
+ createdAt: string;
62
+ }
63
+ export interface Identity {
64
+ agentId: string;
65
+ runId: string;
66
+ }
67
+ export interface AddNodeInput {
68
+ type: string;
69
+ name: string;
70
+ id?: string;
71
+ body?: string;
72
+ props?: Record<string, unknown>;
73
+ source?: string;
74
+ inference?: boolean;
75
+ version?: string;
76
+ rubric?: string;
77
+ aliases?: string[];
78
+ }
79
+ export interface AddEdgeInput {
80
+ type: string;
81
+ from: string;
82
+ to: string;
83
+ props?: Record<string, unknown>;
84
+ source?: string;
85
+ }
86
+ /** A write rejected by an invariant — the caller turns this into a helpful error. */
87
+ export declare class GraphInvariantError extends Error {
88
+ }
89
+ export declare class GraphStore {
90
+ private identity;
91
+ private readonly dir;
92
+ private readonly file;
93
+ private nodes;
94
+ private edges;
95
+ private lastSize;
96
+ private lastMtimeMs;
97
+ constructor(workspaceRoot: string, identity: Identity);
98
+ /** Where the graph lives (for messages). */
99
+ get path(): string;
100
+ private ensureDir;
101
+ /** Re-materialise from disk when the log changed under us (another agent wrote). */
102
+ reloadIfChanged(): void;
103
+ private apply;
104
+ private append;
105
+ addNode(input: AddNodeInput): {
106
+ node: GraphNode;
107
+ created: boolean;
108
+ };
109
+ addEdge(input: AddEdgeInput): GraphEdge;
110
+ /**
111
+ * Version a node: create the replacement, link it with a `supersedes` edge,
112
+ * and flag the old node `supersededBy`. The old node stays addressable
113
+ * (invariant 4) — it just drops out of default query results.
114
+ */
115
+ supersede(oldId: string, replacement: AddNodeInput): {
116
+ oldId: string;
117
+ node: GraphNode;
118
+ edge: GraphEdge;
119
+ };
120
+ getNode(idOrName: string): GraphNode | undefined;
121
+ query(opts: {
122
+ type?: string;
123
+ text?: string;
124
+ id?: string;
125
+ includeSuperseded?: boolean;
126
+ limit?: number;
127
+ }): GraphNode[];
128
+ /**
129
+ * Bounded neighbourhood around a node — the playbook's "context construction
130
+ * from a graph": resolve the entity, expand a hop or two over allowed edge
131
+ * types, and return a small, citable subgraph rather than the whole graph.
132
+ */
133
+ neighbors(opts: {
134
+ idOrName: string;
135
+ hops?: number;
136
+ edgeTypes?: string[];
137
+ limit?: number;
138
+ }): {
139
+ center: GraphNode;
140
+ nodes: GraphNode[];
141
+ edges: GraphEdge[];
142
+ } | null;
143
+ stats(): {
144
+ nodeCount: number;
145
+ edgeCount: number;
146
+ nodesByType: Record<string, number>;
147
+ edgesByType: Record<string, number>;
148
+ superseded: number;
149
+ isolated: number;
150
+ contradictions: number;
151
+ openQuestions: number;
152
+ };
153
+ }