argos-harness 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +21 -0
- package/assets/agents/auditor.md +140 -0
- package/assets/agents/commit-pr-pilot.md +154 -0
- package/assets/agents/explorer.md +93 -0
- package/assets/agents/implementer.md +117 -0
- package/assets/agents/leader.md +149 -0
- package/assets/agents/researcher.md +89 -0
- package/assets/agents/review-readability.md +87 -0
- package/assets/agents/review-reliability.md +100 -0
- package/assets/agents/review-resilience.md +87 -0
- package/assets/agents/review-risk.md +87 -0
- package/assets/agents/reviewer.md +167 -0
- package/assets/agents/ticket-audit.md +129 -0
- package/assets/hooks/argos-guard-destructive.sh +127 -0
- package/assets/hooks/argos-quality-gate.sh +129 -0
- package/assets/managed/aterrizaje.md +24 -0
- package/assets/managed/formato-respuesta.md +21 -0
- package/assets/managed/identidad.md +48 -0
- package/assets/managed/operaciones-seguras.md +14 -0
- package/assets/managed/orquestacion.md +169 -0
- package/assets/output-styles/argos.md +71 -0
- package/assets/skills/ai-sdk-5/SKILL.md +230 -0
- package/assets/skills/angular/SKILL.md +19 -0
- package/assets/skills/angular/references/architecture.md +137 -0
- package/assets/skills/angular/references/core.md +197 -0
- package/assets/skills/angular/references/forms.md +115 -0
- package/assets/skills/angular/references/performance.md +124 -0
- package/assets/skills/apollo-client/SKILL.md +61 -0
- package/assets/skills/app-blueprint/SKILL.md +45 -0
- package/assets/skills/app-blueprint/assets/module-template.md +48 -0
- package/assets/skills/app-blueprint/assets/system-template.md +38 -0
- package/assets/skills/app-blueprint/references/workflow.md +101 -0
- package/assets/skills/app-builder/SKILL.md +43 -0
- package/assets/skills/app-builder/phases/0-product.md +58 -0
- package/assets/skills/app-builder/phases/1-scaffold.md +33 -0
- package/assets/skills/app-builder/phases/10-store.md +40 -0
- package/assets/skills/app-builder/phases/2-data.md +34 -0
- package/assets/skills/app-builder/phases/3-domain.md +33 -0
- package/assets/skills/app-builder/phases/4-ui-nav.md +32 -0
- package/assets/skills/app-builder/phases/5-identity.md +30 -0
- package/assets/skills/app-builder/phases/6-polish.md +34 -0
- package/assets/skills/app-builder/phases/7-brand.md +31 -0
- package/assets/skills/app-builder/phases/8-web.md +30 -0
- package/assets/skills/app-builder/phases/9-docs.md +31 -0
- package/assets/skills/app-ia/SKILL.md +54 -0
- package/assets/skills/astro/SKILL.md +39 -0
- package/assets/skills/axios/SKILL.md +61 -0
- package/assets/skills/branch-pr/SKILL.md +200 -0
- package/assets/skills/bullmq/SKILL.md +55 -0
- package/assets/skills/chained-pr/SKILL.md +48 -0
- package/assets/skills/chained-pr/references/chaining-details.md +99 -0
- package/assets/skills/cognitive-doc-design/SKILL.md +81 -0
- package/assets/skills/comment-writer/SKILL.md +74 -0
- package/assets/skills/dashboard-ia/SKILL.md +54 -0
- package/assets/skills/django-drf/SKILL.md +180 -0
- package/assets/skills/go-testing/SKILL.md +47 -0
- package/assets/skills/go-testing/references/examples.md +89 -0
- package/assets/skills/issue-creation/SKILL.md +223 -0
- package/assets/skills/jira-epic/SKILL.md +306 -0
- package/assets/skills/jira-task/SKILL.md +382 -0
- package/assets/skills/judgment-day/SKILL.md +52 -0
- package/assets/skills/judgment-day/references/prompts-and-formats.md +98 -0
- package/assets/skills/lightsail-deploy/SKILL.md +44 -0
- package/assets/skills/lightsail-deploy/references/runbook.md +102 -0
- package/assets/skills/loop-back-debug/SKILL.md +102 -0
- package/assets/skills/mantine-form/SKILL.md +57 -0
- package/assets/skills/mongoose/SKILL.md +66 -0
- package/assets/skills/nextjs-15/SKILL.md +144 -0
- package/assets/skills/not-boring-mobile/SKILL.md +43 -0
- package/assets/skills/not-boring-mobile/references/not-boring-playbook.md +65 -0
- package/assets/skills/playwright/SKILL.md +315 -0
- package/assets/skills/pr-comments/SKILL.md +93 -0
- package/assets/skills/pr-create/SKILL.md +64 -0
- package/assets/skills/promo-video/SKILL.md +52 -0
- package/assets/skills/promo-video/assets/package.template.json +22 -0
- package/assets/skills/promo-video/assets/promo.template.tsx +469 -0
- package/assets/skills/promo-video/assets/theme.template.ts +27 -0
- package/assets/skills/promo-video/references/pipeline.md +119 -0
- package/assets/skills/promo-video-web/SKILL.md +51 -0
- package/assets/skills/promo-video-web/assets/browser-promo.template.tsx +385 -0
- package/assets/skills/promo-video-web/assets/capture.template.ts +70 -0
- package/assets/skills/promo-video-web/assets/package.template.json +26 -0
- package/assets/skills/promo-video-web/references/pipeline.md +84 -0
- package/assets/skills/pytest/SKILL.md +180 -0
- package/assets/skills/react-19/SKILL.md +118 -0
- package/assets/skills/react-hook-form/SKILL.md +59 -0
- package/assets/skills/react-router/SKILL.md +60 -0
- package/assets/skills/redux-toolkit/SKILL.md +60 -0
- package/assets/skills/review-diff/SKILL.md +101 -0
- package/assets/skills/ship-docs/SKILL.md +45 -0
- package/assets/skills/ship-docs/references/ship-docs-playbook.md +31 -0
- package/assets/skills/skill-creator/SKILL.md +97 -0
- package/assets/skills/skill-creator/assets/SKILL-TEMPLATE.md +68 -0
- package/assets/skills/skill-creator/references/skill-style-guide.md +79 -0
- package/assets/skills/skill-improver/SKILL.md +50 -0
- package/assets/skills/skill-improver/references/skill-style-guide.md +79 -0
- package/assets/skills/socketio/SKILL.md +58 -0
- package/assets/skills/spec-bootstrap/SKILL.md +62 -0
- package/assets/skills/store-ship/SKILL.md +52 -0
- package/assets/skills/store-ship/assets/android-supply.template.md +22 -0
- package/assets/skills/store-ship/assets/eas.template.json +32 -0
- package/assets/skills/store-ship/assets/maestro-flow.template.yaml +27 -0
- package/assets/skills/store-ship/assets/store.config.template.json +28 -0
- package/assets/skills/store-ship/references/pipeline.md +198 -0
- package/assets/skills/stripe/SKILL.md +83 -0
- package/assets/skills/tailwind-4/SKILL.md +193 -0
- package/assets/skills/tamagui/SKILL.md +60 -0
- package/assets/skills/tanstack-query/SKILL.md +58 -0
- package/assets/skills/ticket-intake/SKILL.md +55 -0
- package/assets/skills/typescript/SKILL.md +134 -0
- package/assets/skills/verify-before-done/SKILL.md +111 -0
- package/assets/skills/webapp-rebuilder/SKILL.md +48 -0
- package/assets/skills/webapp-rebuilder/assets/charter-template.md +46 -0
- package/assets/skills/webapp-rebuilder/references/workflow.md +47 -0
- package/assets/skills/winston-logging/SKILL.md +61 -0
- package/assets/skills/work-unit-commits/SKILL.md +84 -0
- package/assets/skills/zod-4/SKILL.md +210 -0
- package/assets/skills/zustand-5/SKILL.md +216 -0
- package/bin/argos.js +6 -0
- package/dist/commands/adopt.d.ts +35 -0
- package/dist/commands/adopt.d.ts.map +1 -0
- package/dist/commands/adopt.js +347 -0
- package/dist/commands/adopt.js.map +1 -0
- package/dist/commands/doctor.d.ts +20 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +478 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/init.d.ts +32 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +358 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/remove.d.ts +62 -0
- package/dist/commands/remove.d.ts.map +1 -0
- package/dist/commands/remove.js +487 -0
- package/dist/commands/remove.js.map +1 -0
- package/dist/commands/workspace.d.ts +73 -0
- package/dist/commands/workspace.d.ts.map +1 -0
- package/dist/commands/workspace.js +354 -0
- package/dist/commands/workspace.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/assets.d.ts +29 -0
- package/dist/lib/assets.d.ts.map +1 -0
- package/dist/lib/assets.js +57 -0
- package/dist/lib/assets.js.map +1 -0
- package/dist/lib/atomic-write.d.ts +17 -0
- package/dist/lib/atomic-write.d.ts.map +1 -0
- package/dist/lib/atomic-write.js +41 -0
- package/dist/lib/atomic-write.js.map +1 -0
- package/dist/lib/backup.d.ts +11 -0
- package/dist/lib/backup.d.ts.map +1 -0
- package/dist/lib/backup.js +42 -0
- package/dist/lib/backup.js.map +1 -0
- package/dist/lib/config.d.ts +36 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +52 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/detect.d.ts +58 -0
- package/dist/lib/detect.d.ts.map +1 -0
- package/dist/lib/detect.js +330 -0
- package/dist/lib/detect.js.map +1 -0
- package/dist/lib/ficha.d.ts +10 -0
- package/dist/lib/ficha.d.ts.map +1 -0
- package/dist/lib/ficha.js +38 -0
- package/dist/lib/ficha.js.map +1 -0
- package/dist/lib/git.d.ts +27 -0
- package/dist/lib/git.d.ts.map +1 -0
- package/dist/lib/git.js +79 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/managed-files.d.ts +35 -0
- package/dist/lib/managed-files.d.ts.map +1 -0
- package/dist/lib/managed-files.js +97 -0
- package/dist/lib/managed-files.js.map +1 -0
- package/dist/lib/markers.d.ts +64 -0
- package/dist/lib/markers.d.ts.map +1 -0
- package/dist/lib/markers.js +157 -0
- package/dist/lib/markers.js.map +1 -0
- package/dist/lib/navori-import.d.ts +42 -0
- package/dist/lib/navori-import.d.ts.map +1 -0
- package/dist/lib/navori-import.js +65 -0
- package/dist/lib/navori-import.js.map +1 -0
- package/dist/lib/openclaw-agents.d.ts +53 -0
- package/dist/lib/openclaw-agents.d.ts.map +1 -0
- package/dist/lib/openclaw-agents.js +118 -0
- package/dist/lib/openclaw-agents.js.map +1 -0
- package/dist/lib/package-root.d.ts +11 -0
- package/dist/lib/package-root.d.ts.map +1 -0
- package/dist/lib/package-root.js +23 -0
- package/dist/lib/package-root.js.map +1 -0
- package/dist/lib/paths.d.ts +11 -0
- package/dist/lib/paths.d.ts.map +1 -0
- package/dist/lib/paths.js +16 -0
- package/dist/lib/paths.js.map +1 -0
- package/dist/lib/settings-merge.d.ts +125 -0
- package/dist/lib/settings-merge.d.ts.map +1 -0
- package/dist/lib/settings-merge.js +373 -0
- package/dist/lib/settings-merge.js.map +1 -0
- package/dist/lib/version.d.ts +3 -0
- package/dist/lib/version.d.ts.map +1 -0
- package/dist/lib/version.js +13 -0
- package/dist/lib/version.js.map +1 -0
- package/dist/lib/which.d.ts +8 -0
- package/dist/lib/which.d.ts.map +1 -0
- package/dist/lib/which.js +30 -0
- package/dist/lib/which.js.map +1 -0
- package/dist/lib/workspaces.d.ts +133 -0
- package/dist/lib/workspaces.d.ts.map +1 -0
- package/dist/lib/workspaces.js +241 -0
- package/dist/lib/workspaces.js.map +1 -0
- package/dist/lib/zod-messages.d.ts +4 -0
- package/dist/lib/zod-messages.d.ts.map +1 -0
- package/dist/lib/zod-messages.js +28 -0
- package/dist/lib/zod-messages.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import { defineCommand } from "citty";
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import pc from "picocolors";
|
|
5
|
+
import { listAgentIds, listSkillFiles, listSkillIds, MANAGED_BLOCK_IDS, readAsset, resolveAssetsDir } from "../lib/assets.js";
|
|
6
|
+
import { writeFileAtomic } from "../lib/atomic-write.js";
|
|
7
|
+
import { createBackup } from "../lib/backup.js";
|
|
8
|
+
import { injectBlock, listBlocks } from "../lib/markers.js";
|
|
9
|
+
import { hasArgosFileMarker, writeManagedFile, writeManagedShellFile } from "../lib/managed-files.js";
|
|
10
|
+
import { resolveArgosHome, resolveClaudeDir } from "../lib/paths.js";
|
|
11
|
+
import { mergeHooksIntoSettings } from "../lib/settings-merge.js";
|
|
12
|
+
import { readCliVersion } from "../lib/version.js";
|
|
13
|
+
/**
|
|
14
|
+
* Ids (basenames under assets/hooks/) of the 2 global hooks argos init
|
|
15
|
+
* installs. See spec 0003 "Hooks globales parametrizados".
|
|
16
|
+
*/ const HOOK_IDS = [
|
|
17
|
+
"argos-guard-destructive",
|
|
18
|
+
"argos-quality-gate"
|
|
19
|
+
];
|
|
20
|
+
/**
|
|
21
|
+
* Outer Claude Code hook timeout (seconds) for argos-quality-gate.sh. Fixed
|
|
22
|
+
* rather than derived from $ARGOS_GATE_TIMEOUT_MS: that env var is read
|
|
23
|
+
* inside the hook at COMMIT time (whatever env the Claude Code session has),
|
|
24
|
+
* not at `argos init` time, so there's nothing meaningful to read here. 600s
|
|
25
|
+
* comfortably covers the hook's own default inner bound (300s) with 2x
|
|
26
|
+
* headroom; a repo whose gate legitimately needs longer than ~590s needs to
|
|
27
|
+
* bump this constant (and rerun `argos init`) alongside its own
|
|
28
|
+
* $ARGOS_GATE_TIMEOUT_MS — not automated in v1.
|
|
29
|
+
*/ const QUALITY_GATE_OUTER_TIMEOUT_SECONDS = 600;
|
|
30
|
+
const STATUS_COUNT_ORDER = [
|
|
31
|
+
"created",
|
|
32
|
+
"updated",
|
|
33
|
+
"unchanged",
|
|
34
|
+
"skipped-foreign",
|
|
35
|
+
"error"
|
|
36
|
+
];
|
|
37
|
+
function summarize(rows) {
|
|
38
|
+
const counts = {
|
|
39
|
+
created: 0,
|
|
40
|
+
updated: 0,
|
|
41
|
+
unchanged: 0,
|
|
42
|
+
"skipped-foreign": 0,
|
|
43
|
+
error: 0
|
|
44
|
+
};
|
|
45
|
+
for (const row of rows)counts[row.status]++;
|
|
46
|
+
const parts = STATUS_COUNT_ORDER.filter((s)=>counts[s] > 0).map((s)=>`${counts[s]} ${s}`);
|
|
47
|
+
return `argos init: ${parts.join(", ")}.`;
|
|
48
|
+
}
|
|
49
|
+
function errorMessage(err) {
|
|
50
|
+
return err instanceof Error ? err.message : String(err);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Write a plain (unmarked) supporting file belonging to an already
|
|
54
|
+
* ownership-checked skill directory — e.g. `references/core.md`,
|
|
55
|
+
* `phases/0-product.md`. Unlike `writeManagedFile`, this never carries or
|
|
56
|
+
* checks the `argos:file` marker itself: ownership for the whole skill
|
|
57
|
+
* directory is decided once, up front, from its `SKILL.md` (see the skills
|
|
58
|
+
* loop in `runInit`), so per-file marker bookkeeping here would be
|
|
59
|
+
* redundant. Reports the same created/updated/unchanged statuses.
|
|
60
|
+
*/ function writePlainFile(destPath, sourceContent) {
|
|
61
|
+
if (!existsSync(destPath)) {
|
|
62
|
+
mkdirSync(dirname(destPath), {
|
|
63
|
+
recursive: true
|
|
64
|
+
});
|
|
65
|
+
writeFileAtomic(destPath, sourceContent);
|
|
66
|
+
return "created";
|
|
67
|
+
}
|
|
68
|
+
const current = readFileSync(destPath, "utf-8");
|
|
69
|
+
if (current === sourceContent) return "unchanged";
|
|
70
|
+
writeFileAtomic(destPath, sourceContent);
|
|
71
|
+
return "updated";
|
|
72
|
+
}
|
|
73
|
+
/** Inject one managed CLAUDE.md block, reporting created/updated/unchanged. */ function injectAndReport(claudeMd, id, version, content) {
|
|
74
|
+
const hadBlock = listBlocks(claudeMd).some((b)=>b.id === id);
|
|
75
|
+
const after = injectBlock(claudeMd, id, version, content);
|
|
76
|
+
const status = after === claudeMd ? "unchanged" : hadBlock ? "updated" : "created";
|
|
77
|
+
return {
|
|
78
|
+
claudeMd: after,
|
|
79
|
+
status
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Core, testable implementation of `argos init`: installs the Argos engine
|
|
84
|
+
* (CLAUDE.md managed blocks + agents/skills/output-style full files +
|
|
85
|
+
* `~/.argos/global.json`) into `resolveClaudeDir()`. Pure function of the
|
|
86
|
+
* filesystem — no process.exit, no console output.
|
|
87
|
+
*/ export function runInit(options = {}) {
|
|
88
|
+
const language = options.language ?? "es";
|
|
89
|
+
const version = readCliVersion();
|
|
90
|
+
const claudeDir = resolveClaudeDir();
|
|
91
|
+
const assetsDir = resolveAssetsDir();
|
|
92
|
+
const rows = [];
|
|
93
|
+
// Backup everything Argos is about to touch, before any write happens. A
|
|
94
|
+
// failed backup means we have no safety net for what's about to be
|
|
95
|
+
// mutated, so it aborts the whole run right here — every subsequent
|
|
96
|
+
// mutation step is skipped, nothing gets touched.
|
|
97
|
+
let backupPath;
|
|
98
|
+
try {
|
|
99
|
+
backupPath = createBackup(claudeDir, [
|
|
100
|
+
"CLAUDE.md",
|
|
101
|
+
"agents",
|
|
102
|
+
"skills",
|
|
103
|
+
"output-styles",
|
|
104
|
+
"hooks",
|
|
105
|
+
"settings.json"
|
|
106
|
+
]);
|
|
107
|
+
} catch (err) {
|
|
108
|
+
const detail = errorMessage(err);
|
|
109
|
+
rows.push({
|
|
110
|
+
path: "backup",
|
|
111
|
+
status: "error",
|
|
112
|
+
detail
|
|
113
|
+
});
|
|
114
|
+
return {
|
|
115
|
+
rows,
|
|
116
|
+
summary: `backup falló — no se tocó nada (${detail}).`,
|
|
117
|
+
exitCode: 1
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
// 1. CLAUDE.md — 5 managed blocks, in order.
|
|
121
|
+
const claudeMdPath = join(claudeDir, "CLAUDE.md");
|
|
122
|
+
let claudeMd = existsSync(claudeMdPath) ? readFileSync(claudeMdPath, "utf-8") : "";
|
|
123
|
+
const blockResults = [];
|
|
124
|
+
for (const id of MANAGED_BLOCK_IDS){
|
|
125
|
+
const content = readAsset(assetsDir, "managed", `${id}.md`).replace(/\n$/, "");
|
|
126
|
+
const result = injectAndReport(claudeMd, id, version, content);
|
|
127
|
+
claudeMd = result.claudeMd;
|
|
128
|
+
blockResults.push({
|
|
129
|
+
id,
|
|
130
|
+
status: result.status
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
try {
|
|
134
|
+
mkdirSync(claudeDir, {
|
|
135
|
+
recursive: true
|
|
136
|
+
});
|
|
137
|
+
writeFileAtomic(claudeMdPath, claudeMd);
|
|
138
|
+
for (const b of blockResults)rows.push({
|
|
139
|
+
path: `CLAUDE.md#${b.id}`,
|
|
140
|
+
status: b.status
|
|
141
|
+
});
|
|
142
|
+
} catch (err) {
|
|
143
|
+
const detail = errorMessage(err);
|
|
144
|
+
for (const id of MANAGED_BLOCK_IDS)rows.push({
|
|
145
|
+
path: `CLAUDE.md#${id}`,
|
|
146
|
+
status: "error",
|
|
147
|
+
detail
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
// 2. Full-file assets: output-style, agents.
|
|
151
|
+
const fullFiles = [
|
|
152
|
+
[
|
|
153
|
+
"output-styles",
|
|
154
|
+
"argos.md"
|
|
155
|
+
],
|
|
156
|
+
...listAgentIds(assetsDir).map((id)=>[
|
|
157
|
+
"agents",
|
|
158
|
+
`${id}.md`
|
|
159
|
+
])
|
|
160
|
+
];
|
|
161
|
+
for (const relPath of fullFiles){
|
|
162
|
+
const source = readAsset(assetsDir, ...relPath);
|
|
163
|
+
const dest = join(claudeDir, ...relPath);
|
|
164
|
+
try {
|
|
165
|
+
const status = writeManagedFile(dest, source, version);
|
|
166
|
+
rows.push({
|
|
167
|
+
path: join(...relPath),
|
|
168
|
+
status
|
|
169
|
+
});
|
|
170
|
+
} catch (err) {
|
|
171
|
+
rows.push({
|
|
172
|
+
path: join(...relPath),
|
|
173
|
+
status: "error",
|
|
174
|
+
detail: errorMessage(err)
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
// 2a. Skills: each skill directory (SKILL.md plus any `references/`,
|
|
179
|
+
// `phases/`, `assets/`, etc. it ships) is installed as a single unit.
|
|
180
|
+
// Ownership sentinel is SKILL.md's `argos:file` marker:
|
|
181
|
+
// - SKILL.md absent, or present WITH the marker → install/update every
|
|
182
|
+
// file the skill ships.
|
|
183
|
+
// - SKILL.md present WITHOUT the marker (foreign/user-modified) → skip
|
|
184
|
+
// every file under that skill dir, untouched — same policy as a single
|
|
185
|
+
// foreign full-file asset above, extended to the whole directory.
|
|
186
|
+
for (const skillId of listSkillIds(assetsDir)){
|
|
187
|
+
const skillMdDest = join(claudeDir, "skills", skillId, "SKILL.md");
|
|
188
|
+
const isForeignSkill = existsSync(skillMdDest) && !hasArgosFileMarker(readFileSync(skillMdDest, "utf-8"));
|
|
189
|
+
for (const relFile of listSkillFiles(assetsDir, skillId)){
|
|
190
|
+
const relParts = relFile.split("/");
|
|
191
|
+
const relPath = join("skills", skillId, ...relParts);
|
|
192
|
+
if (isForeignSkill) {
|
|
193
|
+
rows.push({
|
|
194
|
+
path: relPath,
|
|
195
|
+
status: "skipped-foreign"
|
|
196
|
+
});
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
const source = readAsset(assetsDir, "skills", skillId, ...relParts);
|
|
200
|
+
const dest = join(claudeDir, "skills", skillId, ...relParts);
|
|
201
|
+
try {
|
|
202
|
+
const status = relFile === "SKILL.md" ? writeManagedFile(dest, source, version) : writePlainFile(dest, source);
|
|
203
|
+
rows.push({
|
|
204
|
+
path: relPath,
|
|
205
|
+
status
|
|
206
|
+
});
|
|
207
|
+
} catch (err) {
|
|
208
|
+
rows.push({
|
|
209
|
+
path: relPath,
|
|
210
|
+
status: "error",
|
|
211
|
+
detail: errorMessage(err)
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
// 2b. Global hooks: full-file shell assets, own shell-comment marker,
|
|
217
|
+
// chmod +x. Same skipped-foreign policy as the full-file assets above.
|
|
218
|
+
// Track which hooks actually landed on disk successfully — a hook whose
|
|
219
|
+
// write threw must NEVER get a settings.json entry (see 2c below): a
|
|
220
|
+
// dangling PreToolUse entry pointing at a script that isn't there hard-
|
|
221
|
+
// blocks every subsequent Bash call.
|
|
222
|
+
const hookWriteFailed = new Map();
|
|
223
|
+
for (const id of HOOK_IDS){
|
|
224
|
+
const relPath = [
|
|
225
|
+
"hooks",
|
|
226
|
+
`${id}.sh`
|
|
227
|
+
];
|
|
228
|
+
const source = readAsset(assetsDir, ...relPath);
|
|
229
|
+
const dest = join(claudeDir, ...relPath);
|
|
230
|
+
try {
|
|
231
|
+
const status = writeManagedShellFile(dest, source, version);
|
|
232
|
+
rows.push({
|
|
233
|
+
path: join(...relPath),
|
|
234
|
+
status
|
|
235
|
+
});
|
|
236
|
+
hookWriteFailed.set(id, false);
|
|
237
|
+
} catch (err) {
|
|
238
|
+
rows.push({
|
|
239
|
+
path: join(...relPath),
|
|
240
|
+
status: "error",
|
|
241
|
+
detail: errorMessage(err)
|
|
242
|
+
});
|
|
243
|
+
hookWriteFailed.set(id, true);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
// 2c. settings.json — surgical merge of the 2 PreToolUse hook entries.
|
|
247
|
+
// Only writes/updates entries whose command targets one of the 2 scripts
|
|
248
|
+
// above; every other key and hook in the user's settings.json is left
|
|
249
|
+
// untouched (see lib/settings-merge.ts). Only hooks whose script write
|
|
250
|
+
// actually succeeded get an entry built for them at all.
|
|
251
|
+
const settingsPath = join(claudeDir, "settings.json");
|
|
252
|
+
const allHookSpecs = {
|
|
253
|
+
"argos-guard-destructive": {
|
|
254
|
+
scriptPath: join(claudeDir, "hooks", "argos-guard-destructive.sh"),
|
|
255
|
+
matcher: "Bash",
|
|
256
|
+
timeout: 10,
|
|
257
|
+
statusMessage: "argos: guard-destructive"
|
|
258
|
+
},
|
|
259
|
+
"argos-quality-gate": {
|
|
260
|
+
scriptPath: join(claudeDir, "hooks", "argos-quality-gate.sh"),
|
|
261
|
+
matcher: "Bash",
|
|
262
|
+
timeout: QUALITY_GATE_OUTER_TIMEOUT_SECONDS,
|
|
263
|
+
statusMessage: "argos: quality-gate"
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
const hookSpecs = HOOK_IDS.filter((id)=>!hookWriteFailed.get(id)).map((id)=>allHookSpecs[id]);
|
|
267
|
+
// Any hook whose write just failed also gets its (possibly pre-existing,
|
|
268
|
+
// from an earlier successful run) settings.json entry stripped out — a
|
|
269
|
+
// script that's gone or broken must never be left with a live entry.
|
|
270
|
+
const failedScriptPaths = HOOK_IDS.filter((id)=>hookWriteFailed.get(id)).map((id)=>allHookSpecs[id].scriptPath);
|
|
271
|
+
const mergeResult = mergeHooksIntoSettings(settingsPath, hookSpecs, {
|
|
272
|
+
removeScriptPaths: failedScriptPaths
|
|
273
|
+
});
|
|
274
|
+
rows.push({
|
|
275
|
+
path: "settings.json",
|
|
276
|
+
status: mergeResult.status,
|
|
277
|
+
detail: mergeResult.detail
|
|
278
|
+
});
|
|
279
|
+
// 3. ~/.argos/global.json
|
|
280
|
+
const argosHome = resolveArgosHome();
|
|
281
|
+
const globalJsonPath = join(argosHome, "global.json");
|
|
282
|
+
const globalJsonContent = `${JSON.stringify({
|
|
283
|
+
version,
|
|
284
|
+
language
|
|
285
|
+
}, null, 2)}\n`;
|
|
286
|
+
try {
|
|
287
|
+
const globalJsonExisted = existsSync(globalJsonPath);
|
|
288
|
+
const globalJsonStatus = !globalJsonExisted ? "created" : readFileSync(globalJsonPath, "utf-8") === globalJsonContent ? "unchanged" : "updated";
|
|
289
|
+
mkdirSync(argosHome, {
|
|
290
|
+
recursive: true
|
|
291
|
+
});
|
|
292
|
+
writeFileSync(globalJsonPath, globalJsonContent, "utf-8");
|
|
293
|
+
rows.push({
|
|
294
|
+
path: "global.json",
|
|
295
|
+
status: globalJsonStatus
|
|
296
|
+
});
|
|
297
|
+
} catch (err) {
|
|
298
|
+
rows.push({
|
|
299
|
+
path: "global.json",
|
|
300
|
+
status: "error",
|
|
301
|
+
detail: errorMessage(err)
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
const exitCode = rows.some((r)=>r.status === "error") ? 1 : 0;
|
|
305
|
+
return {
|
|
306
|
+
rows,
|
|
307
|
+
summary: summarize(rows),
|
|
308
|
+
exitCode,
|
|
309
|
+
backupPath
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
export const initCommand = defineCommand({
|
|
313
|
+
meta: {
|
|
314
|
+
name: "init",
|
|
315
|
+
description: "Install the Argos engine into the global Claude Code home."
|
|
316
|
+
},
|
|
317
|
+
args: {
|
|
318
|
+
language: {
|
|
319
|
+
type: "enum",
|
|
320
|
+
options: [
|
|
321
|
+
"es",
|
|
322
|
+
"en"
|
|
323
|
+
],
|
|
324
|
+
default: "es",
|
|
325
|
+
description: "Idioma del motor (global.json)."
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
run ({ args }) {
|
|
329
|
+
const report = runInit({
|
|
330
|
+
language: args.language
|
|
331
|
+
});
|
|
332
|
+
const colorize = (status)=>{
|
|
333
|
+
const padded = status.padEnd(18);
|
|
334
|
+
switch(status){
|
|
335
|
+
case "skipped-foreign":
|
|
336
|
+
return pc.yellow(padded);
|
|
337
|
+
case "created":
|
|
338
|
+
return pc.green(padded);
|
|
339
|
+
case "updated":
|
|
340
|
+
return pc.cyan(padded);
|
|
341
|
+
case "error":
|
|
342
|
+
return pc.red(padded);
|
|
343
|
+
default:
|
|
344
|
+
return pc.dim(padded);
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
for (const row of report.rows){
|
|
348
|
+
const suffix = row.detail ? ` (${row.detail})` : "";
|
|
349
|
+
console.log(`${colorize(row.status)} ${row.path}${suffix}`);
|
|
350
|
+
}
|
|
351
|
+
console.log("");
|
|
352
|
+
console.log(report.summary);
|
|
353
|
+
if (report.backupPath) console.log(`backup en ${report.backupPath}`);
|
|
354
|
+
process.exit(report.exitCode);
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/commands/init.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport pc from \"picocolors\";\nimport {\n listAgentIds,\n listSkillFiles,\n listSkillIds,\n MANAGED_BLOCK_IDS,\n readAsset,\n resolveAssetsDir,\n} from \"../lib/assets.js\";\nimport { writeFileAtomic } from \"../lib/atomic-write.js\";\nimport { createBackup } from \"../lib/backup.js\";\nimport { injectBlock, listBlocks } from \"../lib/markers.js\";\nimport {\n type FileStatus,\n hasArgosFileMarker,\n writeManagedFile,\n writeManagedShellFile,\n} from \"../lib/managed-files.js\";\nimport { resolveArgosHome, resolveClaudeDir } from \"../lib/paths.js\";\nimport { type ArgosHookSpec, mergeHooksIntoSettings } from \"../lib/settings-merge.js\";\nimport { readCliVersion } from \"../lib/version.js\";\n\n/**\n * Ids (basenames under assets/hooks/) of the 2 global hooks argos init\n * installs. See spec 0003 \"Hooks globales parametrizados\".\n */\nconst HOOK_IDS = [\"argos-guard-destructive\", \"argos-quality-gate\"] as const;\n\n/**\n * Outer Claude Code hook timeout (seconds) for argos-quality-gate.sh. Fixed\n * rather than derived from $ARGOS_GATE_TIMEOUT_MS: that env var is read\n * inside the hook at COMMIT time (whatever env the Claude Code session has),\n * not at `argos init` time, so there's nothing meaningful to read here. 600s\n * comfortably covers the hook's own default inner bound (300s) with 2x\n * headroom; a repo whose gate legitimately needs longer than ~590s needs to\n * bump this constant (and rerun `argos init`) alongside its own\n * $ARGOS_GATE_TIMEOUT_MS — not automated in v1.\n */\nconst QUALITY_GATE_OUTER_TIMEOUT_SECONDS = 600;\n\nexport type InitRowStatus = FileStatus | \"error\";\n\nexport interface InitRow {\n path: string;\n status: InitRowStatus;\n detail?: string;\n}\n\nexport interface InitOptions {\n language?: \"es\" | \"en\";\n}\n\nexport interface InitReport {\n rows: InitRow[];\n summary: string;\n exitCode: 0 | 1;\n backupPath?: string;\n}\n\nconst STATUS_COUNT_ORDER: InitRowStatus[] = [\"created\", \"updated\", \"unchanged\", \"skipped-foreign\", \"error\"];\n\nfunction summarize(rows: InitRow[]): string {\n const counts: Record<InitRowStatus, number> = {\n created: 0,\n updated: 0,\n unchanged: 0,\n \"skipped-foreign\": 0,\n error: 0,\n };\n for (const row of rows) counts[row.status]++;\n\n const parts = STATUS_COUNT_ORDER.filter((s) => counts[s] > 0).map((s) => `${counts[s]} ${s}`);\n return `argos init: ${parts.join(\", \")}.`;\n}\n\nfunction errorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\n/**\n * Write a plain (unmarked) supporting file belonging to an already\n * ownership-checked skill directory — e.g. `references/core.md`,\n * `phases/0-product.md`. Unlike `writeManagedFile`, this never carries or\n * checks the `argos:file` marker itself: ownership for the whole skill\n * directory is decided once, up front, from its `SKILL.md` (see the skills\n * loop in `runInit`), so per-file marker bookkeeping here would be\n * redundant. Reports the same created/updated/unchanged statuses.\n */\nfunction writePlainFile(destPath: string, sourceContent: string): FileStatus {\n if (!existsSync(destPath)) {\n mkdirSync(dirname(destPath), { recursive: true });\n writeFileAtomic(destPath, sourceContent);\n return \"created\";\n }\n\n const current = readFileSync(destPath, \"utf-8\");\n if (current === sourceContent) return \"unchanged\";\n\n writeFileAtomic(destPath, sourceContent);\n return \"updated\";\n}\n\n/** Inject one managed CLAUDE.md block, reporting created/updated/unchanged. */\nfunction injectAndReport(claudeMd: string, id: string, version: string, content: string) {\n const hadBlock = listBlocks(claudeMd).some((b) => b.id === id);\n const after = injectBlock(claudeMd, id, version, content);\n const status: FileStatus = after === claudeMd ? \"unchanged\" : hadBlock ? \"updated\" : \"created\";\n return { claudeMd: after, status };\n}\n\n/**\n * Core, testable implementation of `argos init`: installs the Argos engine\n * (CLAUDE.md managed blocks + agents/skills/output-style full files +\n * `~/.argos/global.json`) into `resolveClaudeDir()`. Pure function of the\n * filesystem — no process.exit, no console output.\n */\nexport function runInit(options: InitOptions = {}): InitReport {\n const language = options.language ?? \"es\";\n const version = readCliVersion();\n const claudeDir = resolveClaudeDir();\n const assetsDir = resolveAssetsDir();\n const rows: InitRow[] = [];\n\n // Backup everything Argos is about to touch, before any write happens. A\n // failed backup means we have no safety net for what's about to be\n // mutated, so it aborts the whole run right here — every subsequent\n // mutation step is skipped, nothing gets touched.\n let backupPath: string | undefined;\n try {\n backupPath = createBackup(claudeDir, [\"CLAUDE.md\", \"agents\", \"skills\", \"output-styles\", \"hooks\", \"settings.json\"]);\n } catch (err) {\n const detail = errorMessage(err);\n rows.push({ path: \"backup\", status: \"error\", detail });\n return { rows, summary: `backup falló — no se tocó nada (${detail}).`, exitCode: 1 };\n }\n\n // 1. CLAUDE.md — 5 managed blocks, in order.\n const claudeMdPath = join(claudeDir, \"CLAUDE.md\");\n let claudeMd = existsSync(claudeMdPath) ? readFileSync(claudeMdPath, \"utf-8\") : \"\";\n const blockResults: { id: string; status: FileStatus }[] = [];\n for (const id of MANAGED_BLOCK_IDS) {\n const content = readAsset(assetsDir, \"managed\", `${id}.md`).replace(/\\n$/, \"\");\n const result = injectAndReport(claudeMd, id, version, content);\n claudeMd = result.claudeMd;\n blockResults.push({ id, status: result.status });\n }\n try {\n mkdirSync(claudeDir, { recursive: true });\n writeFileAtomic(claudeMdPath, claudeMd);\n for (const b of blockResults) rows.push({ path: `CLAUDE.md#${b.id}`, status: b.status });\n } catch (err) {\n const detail = errorMessage(err);\n for (const id of MANAGED_BLOCK_IDS) rows.push({ path: `CLAUDE.md#${id}`, status: \"error\", detail });\n }\n\n // 2. Full-file assets: output-style, agents.\n const fullFiles: string[][] = [\n [\"output-styles\", \"argos.md\"],\n ...listAgentIds(assetsDir).map((id) => [\"agents\", `${id}.md`]),\n ];\n for (const relPath of fullFiles) {\n const source = readAsset(assetsDir, ...relPath);\n const dest = join(claudeDir, ...relPath);\n try {\n const status = writeManagedFile(dest, source, version);\n rows.push({ path: join(...relPath), status });\n } catch (err) {\n rows.push({ path: join(...relPath), status: \"error\", detail: errorMessage(err) });\n }\n }\n\n // 2a. Skills: each skill directory (SKILL.md plus any `references/`,\n // `phases/`, `assets/`, etc. it ships) is installed as a single unit.\n // Ownership sentinel is SKILL.md's `argos:file` marker:\n // - SKILL.md absent, or present WITH the marker → install/update every\n // file the skill ships.\n // - SKILL.md present WITHOUT the marker (foreign/user-modified) → skip\n // every file under that skill dir, untouched — same policy as a single\n // foreign full-file asset above, extended to the whole directory.\n for (const skillId of listSkillIds(assetsDir)) {\n const skillMdDest = join(claudeDir, \"skills\", skillId, \"SKILL.md\");\n const isForeignSkill = existsSync(skillMdDest) && !hasArgosFileMarker(readFileSync(skillMdDest, \"utf-8\"));\n\n for (const relFile of listSkillFiles(assetsDir, skillId)) {\n const relParts = relFile.split(\"/\");\n const relPath = join(\"skills\", skillId, ...relParts);\n\n if (isForeignSkill) {\n rows.push({ path: relPath, status: \"skipped-foreign\" });\n continue;\n }\n\n const source = readAsset(assetsDir, \"skills\", skillId, ...relParts);\n const dest = join(claudeDir, \"skills\", skillId, ...relParts);\n try {\n const status = relFile === \"SKILL.md\" ? writeManagedFile(dest, source, version) : writePlainFile(dest, source);\n rows.push({ path: relPath, status });\n } catch (err) {\n rows.push({ path: relPath, status: \"error\", detail: errorMessage(err) });\n }\n }\n }\n\n // 2b. Global hooks: full-file shell assets, own shell-comment marker,\n // chmod +x. Same skipped-foreign policy as the full-file assets above.\n // Track which hooks actually landed on disk successfully — a hook whose\n // write threw must NEVER get a settings.json entry (see 2c below): a\n // dangling PreToolUse entry pointing at a script that isn't there hard-\n // blocks every subsequent Bash call.\n const hookWriteFailed = new Map<(typeof HOOK_IDS)[number], boolean>();\n for (const id of HOOK_IDS) {\n const relPath = [\"hooks\", `${id}.sh`];\n const source = readAsset(assetsDir, ...relPath);\n const dest = join(claudeDir, ...relPath);\n try {\n const status = writeManagedShellFile(dest, source, version);\n rows.push({ path: join(...relPath), status });\n hookWriteFailed.set(id, false);\n } catch (err) {\n rows.push({ path: join(...relPath), status: \"error\", detail: errorMessage(err) });\n hookWriteFailed.set(id, true);\n }\n }\n\n // 2c. settings.json — surgical merge of the 2 PreToolUse hook entries.\n // Only writes/updates entries whose command targets one of the 2 scripts\n // above; every other key and hook in the user's settings.json is left\n // untouched (see lib/settings-merge.ts). Only hooks whose script write\n // actually succeeded get an entry built for them at all.\n const settingsPath = join(claudeDir, \"settings.json\");\n const allHookSpecs: Record<(typeof HOOK_IDS)[number], ArgosHookSpec> = {\n \"argos-guard-destructive\": {\n scriptPath: join(claudeDir, \"hooks\", \"argos-guard-destructive.sh\"),\n matcher: \"Bash\",\n timeout: 10,\n statusMessage: \"argos: guard-destructive\",\n },\n \"argos-quality-gate\": {\n scriptPath: join(claudeDir, \"hooks\", \"argos-quality-gate.sh\"),\n matcher: \"Bash\",\n timeout: QUALITY_GATE_OUTER_TIMEOUT_SECONDS,\n statusMessage: \"argos: quality-gate\",\n },\n };\n const hookSpecs: ArgosHookSpec[] = HOOK_IDS.filter((id) => !hookWriteFailed.get(id)).map((id) => allHookSpecs[id]);\n // Any hook whose write just failed also gets its (possibly pre-existing,\n // from an earlier successful run) settings.json entry stripped out — a\n // script that's gone or broken must never be left with a live entry.\n const failedScriptPaths = HOOK_IDS.filter((id) => hookWriteFailed.get(id)).map((id) => allHookSpecs[id].scriptPath);\n const mergeResult = mergeHooksIntoSettings(settingsPath, hookSpecs, { removeScriptPaths: failedScriptPaths });\n rows.push({ path: \"settings.json\", status: mergeResult.status, detail: mergeResult.detail });\n\n // 3. ~/.argos/global.json\n const argosHome = resolveArgosHome();\n const globalJsonPath = join(argosHome, \"global.json\");\n const globalJsonContent = `${JSON.stringify({ version, language }, null, 2)}\\n`;\n try {\n const globalJsonExisted = existsSync(globalJsonPath);\n const globalJsonStatus: FileStatus = !globalJsonExisted\n ? \"created\"\n : readFileSync(globalJsonPath, \"utf-8\") === globalJsonContent\n ? \"unchanged\"\n : \"updated\";\n mkdirSync(argosHome, { recursive: true });\n writeFileSync(globalJsonPath, globalJsonContent, \"utf-8\");\n rows.push({ path: \"global.json\", status: globalJsonStatus });\n } catch (err) {\n rows.push({ path: \"global.json\", status: \"error\", detail: errorMessage(err) });\n }\n\n const exitCode: 0 | 1 = rows.some((r) => r.status === \"error\") ? 1 : 0;\n return { rows, summary: summarize(rows), exitCode, backupPath };\n}\n\nexport const initCommand = defineCommand({\n meta: {\n name: \"init\",\n description: \"Install the Argos engine into the global Claude Code home.\",\n },\n args: {\n language: {\n type: \"enum\",\n options: [\"es\", \"en\"],\n default: \"es\",\n description: \"Idioma del motor (global.json).\",\n },\n },\n run({ args }) {\n const report = runInit({ language: args.language as \"es\" | \"en\" });\n\n const colorize = (status: InitRowStatus): string => {\n const padded = status.padEnd(18);\n switch (status) {\n case \"skipped-foreign\":\n return pc.yellow(padded);\n case \"created\":\n return pc.green(padded);\n case \"updated\":\n return pc.cyan(padded);\n case \"error\":\n return pc.red(padded);\n default:\n return pc.dim(padded);\n }\n };\n for (const row of report.rows) {\n const suffix = row.detail ? ` (${row.detail})` : \"\";\n console.log(`${colorize(row.status)} ${row.path}${suffix}`);\n }\n console.log(\"\");\n console.log(report.summary);\n if (report.backupPath) console.log(`backup en ${report.backupPath}`);\n\n process.exit(report.exitCode);\n },\n});\n"],"names":["defineCommand","existsSync","mkdirSync","readFileSync","writeFileSync","dirname","join","pc","listAgentIds","listSkillFiles","listSkillIds","MANAGED_BLOCK_IDS","readAsset","resolveAssetsDir","writeFileAtomic","createBackup","injectBlock","listBlocks","hasArgosFileMarker","writeManagedFile","writeManagedShellFile","resolveArgosHome","resolveClaudeDir","mergeHooksIntoSettings","readCliVersion","HOOK_IDS","QUALITY_GATE_OUTER_TIMEOUT_SECONDS","STATUS_COUNT_ORDER","summarize","rows","counts","created","updated","unchanged","error","row","status","parts","filter","s","map","errorMessage","err","Error","message","String","writePlainFile","destPath","sourceContent","recursive","current","injectAndReport","claudeMd","id","version","content","hadBlock","some","b","after","runInit","options","language","claudeDir","assetsDir","backupPath","detail","push","path","summary","exitCode","claudeMdPath","blockResults","replace","result","fullFiles","relPath","source","dest","skillId","skillMdDest","isForeignSkill","relFile","relParts","split","hookWriteFailed","Map","set","settingsPath","allHookSpecs","scriptPath","matcher","timeout","statusMessage","hookSpecs","get","failedScriptPaths","mergeResult","removeScriptPaths","argosHome","globalJsonPath","globalJsonContent","JSON","stringify","globalJsonExisted","globalJsonStatus","r","initCommand","meta","name","description","args","type","default","run","report","colorize","padded","padEnd","yellow","green","cyan","red","dim","suffix","console","log","process","exit"],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Uninstaller for `argos init`: the mirror image of `runInit` (see
|
|
3
|
+
* commands/init.ts). Removes only what Argos itself owns — a managed
|
|
4
|
+
* CLAUDE.md block, a file carrying the `argos:file`/shell marker, or a
|
|
5
|
+
* settings.json hook entry pointing at an Argos script — and leaves every
|
|
6
|
+
* foreign file, block, and entry byte-identical.
|
|
7
|
+
*
|
|
8
|
+
* Scope: this command only touches `~/.claude` (via `resolveClaudeDir()`)
|
|
9
|
+
* and, with `--purge`, `~/.argos` (via `resolveArgosHome()`) — the global
|
|
10
|
+
* Argos engine and its registry. Repo-side artifacts are intentionally out
|
|
11
|
+
* of scope and are NEVER touched here: a repo's own `argos.config.json` and
|
|
12
|
+
* the "ficha" managed block `argos adopt` writes into that repo's own
|
|
13
|
+
* `CLAUDE.md` both survive `remove` untouched, including `remove --purge`.
|
|
14
|
+
* (See the final "scope" row every report ends with.)
|
|
15
|
+
*/
|
|
16
|
+
export type RemoveRowStatus = "removed" | "would-remove" | "skipped-foreign" | "warning" | "info" | "error";
|
|
17
|
+
export type RemoveRowCategory = "claude-md-block" | "agents-file" | "skills-file" | "output-styles-file" | "hooks-file" | "settings-entries" | "argos-home" | "scope-note";
|
|
18
|
+
export interface RemoveRow {
|
|
19
|
+
path: string;
|
|
20
|
+
category: RemoveRowCategory;
|
|
21
|
+
status: RemoveRowStatus;
|
|
22
|
+
detail?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface RemoveOptions {
|
|
25
|
+
/** Actually perform the removal. Default false = dry-run preview, touches nothing on disk. */
|
|
26
|
+
apply?: boolean;
|
|
27
|
+
/** Also remove ~/.argos data (registry, global.json, backups). Backups are removed LAST. */
|
|
28
|
+
purge?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export interface RemoveReport {
|
|
31
|
+
rows: RemoveRow[];
|
|
32
|
+
summary: string;
|
|
33
|
+
exitCode: 0 | 1;
|
|
34
|
+
backupPath?: string;
|
|
35
|
+
/** Non-fatal warnings surfaced alongside the report, e.g. the --purge/backups tradeoff. */
|
|
36
|
+
warnings: string[];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Core, testable implementation of `argos remove`: uninstalls everything
|
|
40
|
+
* `runInit` (commands/init.ts) installs into `resolveClaudeDir()`. Pure
|
|
41
|
+
* function of the filesystem — no process.exit, no console output.
|
|
42
|
+
*
|
|
43
|
+
* Preview by default (`apply: false`): computes the full report without
|
|
44
|
+
* writing anything. `apply: true` performs the removal, backing up
|
|
45
|
+
* everything affected first (same `createBackup` call `runInit` makes,
|
|
46
|
+
* before any mutation). `purge: true` additionally removes `~/.argos` data
|
|
47
|
+
* (kept by default) — backups are removed last and always warned about.
|
|
48
|
+
*/
|
|
49
|
+
export declare function runRemove(options?: RemoveOptions): RemoveReport;
|
|
50
|
+
export declare const removeCommand: import("citty").CommandDef<{
|
|
51
|
+
readonly apply: {
|
|
52
|
+
readonly type: "boolean";
|
|
53
|
+
readonly default: false;
|
|
54
|
+
readonly description: "Actually perform the removal (default: dry-run preview, touches nothing).";
|
|
55
|
+
};
|
|
56
|
+
readonly purge: {
|
|
57
|
+
readonly type: "boolean";
|
|
58
|
+
readonly default: false;
|
|
59
|
+
readonly description: "Also remove ~/.argos data (registry, global.json, backups). Irreversible.";
|
|
60
|
+
};
|
|
61
|
+
}>;
|
|
62
|
+
//# sourceMappingURL=remove.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remove.d.ts","sourceRoot":"","sources":["../../src/commands/remove.ts"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,cAAc,GAAG,iBAAiB,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;AAE5G,MAAM,MAAM,iBAAiB,GACzB,iBAAiB,GACjB,aAAa,GACb,aAAa,GACb,oBAAoB,GACpB,YAAY,GACZ,kBAAkB,GAClB,YAAY,GACZ,YAAY,CAAC;AAEjB,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,8FAA8F;IAC9F,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,4FAA4F;IAC5F,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2FAA2F;IAC3F,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AA2RD;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,OAAO,GAAE,aAAkB,GAAG,YAAY,CA4DnE;AAED,eAAO,MAAM,aAAa;;;;;;;;;;;EAkDxB,CAAC"}
|