@groundnuty/macf 0.2.0-rc.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.
Files changed (124) hide show
  1. package/dist/.build-info.json +4 -0
  2. package/dist/cli/build-info.d.ts +38 -0
  3. package/dist/cli/build-info.d.ts.map +1 -0
  4. package/dist/cli/build-info.js +119 -0
  5. package/dist/cli/build-info.js.map +1 -0
  6. package/dist/cli/claude-sh.d.ts +42 -0
  7. package/dist/cli/claude-sh.d.ts.map +1 -0
  8. package/dist/cli/claude-sh.js +247 -0
  9. package/dist/cli/claude-sh.js.map +1 -0
  10. package/dist/cli/commands/cd.d.ts +6 -0
  11. package/dist/cli/commands/cd.d.ts.map +1 -0
  12. package/dist/cli/commands/cd.js +17 -0
  13. package/dist/cli/commands/cd.js.map +1 -0
  14. package/dist/cli/commands/certs.d.ts +33 -0
  15. package/dist/cli/commands/certs.d.ts.map +1 -0
  16. package/dist/cli/commands/certs.js +233 -0
  17. package/dist/cli/commands/certs.js.map +1 -0
  18. package/dist/cli/commands/doctor.d.ts +91 -0
  19. package/dist/cli/commands/doctor.d.ts.map +1 -0
  20. package/dist/cli/commands/doctor.js +235 -0
  21. package/dist/cli/commands/doctor.js.map +1 -0
  22. package/dist/cli/commands/init.d.ts +37 -0
  23. package/dist/cli/commands/init.d.ts.map +1 -0
  24. package/dist/cli/commands/init.js +279 -0
  25. package/dist/cli/commands/init.js.map +1 -0
  26. package/dist/cli/commands/list.d.ts +5 -0
  27. package/dist/cli/commands/list.d.ts.map +1 -0
  28. package/dist/cli/commands/list.js +21 -0
  29. package/dist/cli/commands/list.js.map +1 -0
  30. package/dist/cli/commands/migrate-ca-key.d.ts +36 -0
  31. package/dist/cli/commands/migrate-ca-key.d.ts.map +1 -0
  32. package/dist/cli/commands/migrate-ca-key.js +92 -0
  33. package/dist/cli/commands/migrate-ca-key.js.map +1 -0
  34. package/dist/cli/commands/peers.d.ts +8 -0
  35. package/dist/cli/commands/peers.d.ts.map +1 -0
  36. package/dist/cli/commands/peers.js +45 -0
  37. package/dist/cli/commands/peers.js.map +1 -0
  38. package/dist/cli/commands/repo-init.d.ts +43 -0
  39. package/dist/cli/commands/repo-init.d.ts.map +1 -0
  40. package/dist/cli/commands/repo-init.js +304 -0
  41. package/dist/cli/commands/repo-init.js.map +1 -0
  42. package/dist/cli/commands/rules-refresh.d.ts +14 -0
  43. package/dist/cli/commands/rules-refresh.d.ts.map +1 -0
  44. package/dist/cli/commands/rules-refresh.js +67 -0
  45. package/dist/cli/commands/rules-refresh.js.map +1 -0
  46. package/dist/cli/commands/self-update.d.ts +14 -0
  47. package/dist/cli/commands/self-update.d.ts.map +1 -0
  48. package/dist/cli/commands/self-update.js +112 -0
  49. package/dist/cli/commands/self-update.js.map +1 -0
  50. package/dist/cli/commands/status.d.ts +9 -0
  51. package/dist/cli/commands/status.d.ts.map +1 -0
  52. package/dist/cli/commands/status.js +90 -0
  53. package/dist/cli/commands/status.js.map +1 -0
  54. package/dist/cli/commands/update.d.ts +25 -0
  55. package/dist/cli/commands/update.d.ts.map +1 -0
  56. package/dist/cli/commands/update.js +316 -0
  57. package/dist/cli/commands/update.js.map +1 -0
  58. package/dist/cli/config.d.ts +103 -0
  59. package/dist/cli/config.d.ts.map +1 -0
  60. package/dist/cli/config.js +224 -0
  61. package/dist/cli/config.js.map +1 -0
  62. package/dist/cli/index.d.ts +3 -0
  63. package/dist/cli/index.d.ts.map +1 -0
  64. package/dist/cli/index.js +245 -0
  65. package/dist/cli/index.js.map +1 -0
  66. package/dist/cli/plugin-fetcher.d.ts +20 -0
  67. package/dist/cli/plugin-fetcher.d.ts.map +1 -0
  68. package/dist/cli/plugin-fetcher.js +83 -0
  69. package/dist/cli/plugin-fetcher.js.map +1 -0
  70. package/dist/cli/prompt.d.ts +17 -0
  71. package/dist/cli/prompt.d.ts.map +1 -0
  72. package/dist/cli/prompt.js +109 -0
  73. package/dist/cli/prompt.js.map +1 -0
  74. package/dist/cli/registry-helper.d.ts +11 -0
  75. package/dist/cli/registry-helper.d.ts.map +1 -0
  76. package/dist/cli/registry-helper.js +18 -0
  77. package/dist/cli/registry-helper.js.map +1 -0
  78. package/dist/cli/rules.d.ts +39 -0
  79. package/dist/cli/rules.d.ts.map +1 -0
  80. package/dist/cli/rules.js +112 -0
  81. package/dist/cli/rules.js.map +1 -0
  82. package/dist/cli/settings-writer.d.ts +97 -0
  83. package/dist/cli/settings-writer.d.ts.map +1 -0
  84. package/dist/cli/settings-writer.js +270 -0
  85. package/dist/cli/settings-writer.js.map +1 -0
  86. package/dist/cli/version-resolver.d.ts +73 -0
  87. package/dist/cli/version-resolver.d.ts.map +1 -0
  88. package/dist/cli/version-resolver.js +238 -0
  89. package/dist/cli/version-resolver.js.map +1 -0
  90. package/dist/index.d.ts +19 -0
  91. package/dist/index.d.ts.map +1 -0
  92. package/dist/index.js +22 -0
  93. package/dist/index.js.map +1 -0
  94. package/dist/plugin/bin/macf-plugin-cli.d.ts +13 -0
  95. package/dist/plugin/bin/macf-plugin-cli.d.ts.map +1 -0
  96. package/dist/plugin/bin/macf-plugin-cli.js +127 -0
  97. package/dist/plugin/bin/macf-plugin-cli.js.map +1 -0
  98. package/dist/plugin/lib/format.d.ts +40 -0
  99. package/dist/plugin/lib/format.d.ts.map +1 -0
  100. package/dist/plugin/lib/format.js +137 -0
  101. package/dist/plugin/lib/format.js.map +1 -0
  102. package/dist/plugin/lib/health.d.ts +2 -0
  103. package/dist/plugin/lib/health.d.ts.map +1 -0
  104. package/dist/plugin/lib/health.js +6 -0
  105. package/dist/plugin/lib/health.js.map +1 -0
  106. package/dist/plugin/lib/index.d.ts +7 -0
  107. package/dist/plugin/lib/index.d.ts.map +1 -0
  108. package/dist/plugin/lib/index.js +5 -0
  109. package/dist/plugin/lib/index.js.map +1 -0
  110. package/dist/plugin/lib/registry.d.ts +18 -0
  111. package/dist/plugin/lib/registry.d.ts.map +1 -0
  112. package/dist/plugin/lib/registry.js +17 -0
  113. package/dist/plugin/lib/registry.js.map +1 -0
  114. package/dist/plugin/lib/work.d.ts +13 -0
  115. package/dist/plugin/lib/work.d.ts.map +1 -0
  116. package/dist/plugin/lib/work.js +27 -0
  117. package/dist/plugin/lib/work.js.map +1 -0
  118. package/package.json +43 -0
  119. package/plugin/rules/coordination.md +224 -0
  120. package/scripts/check-gh-token.sh +102 -0
  121. package/scripts/macf-gh-token.sh +130 -0
  122. package/scripts/macf-whoami.sh +51 -0
  123. package/scripts/tmux-send-to-claude.sh +51 -0
  124. package/scripts/write-build-info.mjs +48 -0
@@ -0,0 +1,90 @@
1
+ import { loadAllAgents, readAgentConfig, agentCertPath, agentKeyPath, tokenSourceFromConfig } from '../config.js';
2
+ import { toVariableSegment } from '@groundnuty/macf-core';
3
+ import { createClientFromConfig } from '../registry-helper.js';
4
+ import { createRegistryFromConfig } from '@groundnuty/macf-core';
5
+ import { generateToken } from '@groundnuty/macf-core';
6
+ // Shared with `src/plugin/lib/health.ts` — see ultrareview finding A3.
7
+ import { pingAgentHealth } from '@groundnuty/macf-core';
8
+ function formatUptime(seconds) {
9
+ if (seconds < 60)
10
+ return `${seconds}s`;
11
+ if (seconds < 3600)
12
+ return `${Math.floor(seconds / 60)}m`;
13
+ const h = Math.floor(seconds / 3600);
14
+ const m = Math.floor((seconds % 3600) / 60);
15
+ return m > 0 ? `${h}h${m}m` : `${h}h`;
16
+ }
17
+ /**
18
+ * Show status of registered agents by pinging their /health endpoints.
19
+ *
20
+ * If projectDir is given, uses that project's config for registry access
21
+ * (scopes the view to that project's peers). Otherwise loads all agents
22
+ * from the global index and uses the first one's config.
23
+ */
24
+ export async function showStatus(projectDir) {
25
+ const agents = loadAllAgents();
26
+ // Pick the config + path that drives registry access and token generation.
27
+ let driverConfig;
28
+ let driverPath;
29
+ if (projectDir) {
30
+ const c = readAgentConfig(projectDir);
31
+ if (!c) {
32
+ console.error(`Could not read agent config at ${projectDir}/.macf/macf-agent.json`);
33
+ return;
34
+ }
35
+ driverConfig = c;
36
+ driverPath = projectDir;
37
+ }
38
+ else {
39
+ if (agents.length === 0) {
40
+ console.log('No agents configured. Run `macf init` first.');
41
+ return;
42
+ }
43
+ driverConfig = agents[0].config;
44
+ driverPath = agents[0].path;
45
+ }
46
+ const token = await generateToken(tokenSourceFromConfig(driverPath, driverConfig));
47
+ const registry = createRegistryFromConfig(driverConfig.registry, driverConfig.project, token);
48
+ // Get CA cert from registry for mTLS pings (raw PEM, not via Registry which wraps as AgentInfo)
49
+ const client = createClientFromConfig(driverConfig.registry, token);
50
+ const caCertPem = await client.readVariable(`${toVariableSegment(driverConfig.project)}_CA_CERT`);
51
+ if (!caCertPem) {
52
+ console.log('CA certificate not found in registry. Run `macf certs init` first.');
53
+ return;
54
+ }
55
+ const peers = await registry.list('');
56
+ console.log('macf agents:\n');
57
+ for (const peer of peers) {
58
+ // peer.name comes back uppercased from the registry (toVariableSegment),
59
+ // so compare in that space rather than the original-case agent_name.
60
+ const localAgent = agents.find(a => toVariableSegment(a.config.agent_name) === peer.name);
61
+ const certP = localAgent ? agentCertPath(localAgent.path) : '';
62
+ const keyP = localAgent ? agentKeyPath(localAgent.path) : '';
63
+ const health = await pingAgentHealth({
64
+ host: peer.info.host,
65
+ port: peer.info.port,
66
+ caCertPem,
67
+ certPath: certP,
68
+ keyPath: keyP,
69
+ });
70
+ if (health) {
71
+ const uptime = formatUptime(health.uptime_seconds);
72
+ const issue = health.current_issue ? `issue #${health.current_issue}` : 'idle';
73
+ console.log(` ${peer.name.padEnd(18)} ${peer.info.host}:${peer.info.port}`.padEnd(48) +
74
+ `online uptime ${uptime.padEnd(8)} ${issue}`);
75
+ }
76
+ else {
77
+ console.log(` ${peer.name.padEnd(18)} ${'—'.padEnd(28)}offline`);
78
+ }
79
+ }
80
+ // Show any local agents not in registry. Compare in sanitized space
81
+ // since that's what the registry stores.
82
+ for (const { config } of agents) {
83
+ const sanitized = toVariableSegment(config.agent_name);
84
+ const inRegistry = peers.some(p => p.name === sanitized);
85
+ if (!inRegistry) {
86
+ console.log(` ${config.agent_name.padEnd(18)} ${'—'.padEnd(28)}not registered`);
87
+ }
88
+ }
89
+ }
90
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { VersionPins } from '../config.js';
2
+ import type { ResolvedVersions } from '../version-resolver.js';
3
+ export interface UpdateOptions {
4
+ readonly all: boolean;
5
+ readonly cli: boolean;
6
+ readonly plugin: boolean;
7
+ readonly actions: boolean;
8
+ readonly yes: boolean;
9
+ readonly dryRun: boolean;
10
+ }
11
+ type Component = 'cli' | 'plugin' | 'actions';
12
+ interface DiffRow {
13
+ readonly component: Component;
14
+ readonly current: string;
15
+ readonly latest: string;
16
+ readonly status: 'update' | 'same' | 'not_published' | 'network_error' | 'rate_limited' | 'invalid_response';
17
+ }
18
+ export declare function buildDiff(current: VersionPins, resolved: ResolvedVersions): readonly DiffRow[];
19
+ export declare function renderDiff(diff: readonly DiffRow[]): string;
20
+ /**
21
+ * Main entry. Returns exit code (0 success/noop, 1 failure).
22
+ */
23
+ export declare function update(projectDir: string, opts: UpdateOptions): Promise<number>;
24
+ export {};
25
+ //# sourceMappingURL=update.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/update.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED,KAAK,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,CAAC;AAa9C,UAAU,OAAO;IACf,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAKxB,QAAQ,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,GAAG,eAAe,GAAG,eAAe,GAAG,cAAc,GAAG,kBAAkB,CAAC;CAC9G;AAED,wBAAgB,SAAS,CACvB,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,gBAAgB,GACzB,SAAS,OAAO,EAAE,CAepB;AAgCD,wBAAgB,UAAU,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,GAAG,MAAM,CAM3D;AAmBD;;GAEG;AACH,wBAAsB,MAAM,CAC1B,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,MAAM,CAAC,CAyNjB"}
@@ -0,0 +1,316 @@
1
+ /**
2
+ * macf update: read version pins from macf-agent.json, fetch latest available
3
+ * for each component, show a diff, and bump selected pins.
4
+ *
5
+ * Replaces the earlier plugin-update placeholder (P4). With PR #4 adding
6
+ * version pins, this command is the canonical bumper.
7
+ */
8
+ import { createInterface } from 'node:readline';
9
+ import { existsSync, readdirSync } from 'node:fs';
10
+ import { readAgentConfig, writeAgentConfig, tokenSourceFromConfig } from '../config.js';
11
+ import { resolveLatestVersions } from '../version-resolver.js';
12
+ import { copyCanonicalRules, copyCanonicalScripts, findCliPackageRoot } from '../rules.js';
13
+ import { installGhTokenHook, installPluginSkillPermissions, installSandboxFdAllowRead } from '../settings-writer.js';
14
+ import { detectStaleDist, detectUnknownFreshness } from '../build-info.js';
15
+ import { fetchPluginToWorkspace, workspacePluginDir } from '../plugin-fetcher.js';
16
+ import { writeClaudeSh } from '../claude-sh.js';
17
+ import { createClientFromConfig } from '../registry-helper.js';
18
+ import { generateToken } from '@groundnuty/macf-core';
19
+ import { promptPassword, PromptCancelled } from '../prompt.js';
20
+ import { migrateCaKeyToV2, formatMigrationResult } from './migrate-ca-key.js';
21
+ const ALL_COMPONENTS = ['cli', 'plugin', 'actions'];
22
+ function prompt(message) {
23
+ const rl = createInterface({ input: process.stdin, output: process.stderr });
24
+ return new Promise((resolve) => {
25
+ rl.question(message, (answer) => {
26
+ rl.close();
27
+ resolve(answer);
28
+ });
29
+ });
30
+ }
31
+ export function buildDiff(current, resolved) {
32
+ return ALL_COMPONENTS.map(component => {
33
+ const cur = current[component];
34
+ const lat = resolved.versions[component];
35
+ const source = resolved.sources[component];
36
+ if (source !== 'ok') {
37
+ return { component, current: cur, latest: lat, status: source };
38
+ }
39
+ return {
40
+ component,
41
+ current: cur,
42
+ latest: lat,
43
+ status: cur === lat ? 'same' : 'update',
44
+ };
45
+ });
46
+ }
47
+ /**
48
+ * Does the .macf/plugin/ dir need a re-fetch? True if the dir doesn't
49
+ * exist OR exists but is empty. `existsSync` alone returns true for an
50
+ * empty dir, which misses the repair case (e.g. workspaces init'd before
51
+ * #60 merged where the directory was created but never populated).
52
+ */
53
+ function pluginDirNeedsRepair(dir) {
54
+ if (!existsSync(dir))
55
+ return true;
56
+ return readdirSync(dir).length === 0;
57
+ }
58
+ function formatRow(row) {
59
+ const name = row.component.padEnd(10);
60
+ const cur = row.current.padEnd(10);
61
+ const lat = row.latest.padEnd(10);
62
+ let statusText;
63
+ switch (row.status) {
64
+ case 'update':
65
+ statusText = '⬆ update available';
66
+ break;
67
+ case 'same':
68
+ statusText = '✓ up to date';
69
+ break;
70
+ // Distinct messages for each failure mode so operators don't
71
+ // chase phantom network issues when the component simply hasn't
72
+ // been published yet (#111 C2).
73
+ case 'not_published':
74
+ statusText = '· not yet published (using cached)';
75
+ break;
76
+ case 'network_error':
77
+ statusText = '? fetch failed (network) — using cached';
78
+ break;
79
+ case 'rate_limited':
80
+ statusText = '? rate-limited (set GH_TOKEN to raise anon 60 req/h) — using cached';
81
+ break;
82
+ case 'invalid_response':
83
+ statusText = '? unexpected response — using cached';
84
+ break;
85
+ }
86
+ return `${name} ${cur} ${lat} ${statusText}`;
87
+ }
88
+ export function renderDiff(diff) {
89
+ const lines = [];
90
+ lines.push('Component Current Latest Status');
91
+ lines.push('---------- ---------- ---------- --------');
92
+ for (const row of diff)
93
+ lines.push(formatRow(row));
94
+ return lines.join('\n');
95
+ }
96
+ function selectedComponents(opts) {
97
+ if (opts.all)
98
+ return ALL_COMPONENTS;
99
+ const selected = [];
100
+ if (opts.cli)
101
+ selected.push('cli');
102
+ if (opts.plugin)
103
+ selected.push('plugin');
104
+ if (opts.actions)
105
+ selected.push('actions');
106
+ return selected;
107
+ }
108
+ async function confirmBump(row, autoYes) {
109
+ if (autoYes)
110
+ return true;
111
+ const answer = await prompt(`Update ${row.component} from ${row.current} to ${row.latest}? [y/N]: `);
112
+ return answer.trim().toLowerCase() === 'y' || answer.trim().toLowerCase() === 'yes';
113
+ }
114
+ /**
115
+ * Main entry. Returns exit code (0 success/noop, 1 failure).
116
+ */
117
+ export async function update(projectDir, opts) {
118
+ const config = readAgentConfig(projectDir);
119
+ if (!config) {
120
+ console.error('No macf-agent.json found. Run `macf init` first.');
121
+ return 1;
122
+ }
123
+ // Stale-dist detection (#144): warn if the installed CLI's dist/ is
124
+ // behind the source repo's current HEAD, so operators catch silent
125
+ // no-op behavior before it bites them. Never blocks the update run.
126
+ const cliPackageRoot = findCliPackageRoot();
127
+ const stale = detectStaleDist(cliPackageRoot);
128
+ if (stale) {
129
+ console.warn(`Warning: the installed macf CLI dist/ is stale.\n` +
130
+ ` built from: ${stale.buildCommit.slice(0, 7)} (at ${stale.builtAt})\n` +
131
+ ` source HEAD: ${stale.currentCommit.slice(0, 7)}\n` +
132
+ ` Features merged after ${stale.buildCommit.slice(0, 7)} will not apply.\n` +
133
+ ` Fix: run \`macf self-update\` (or \`cd ${cliPackageRoot} && npm run build\`).\n` +
134
+ ` Note: stale-dist detection only fires for CLI versions >= 0.1.1 (#144).\n`);
135
+ }
136
+ else {
137
+ const unknown = detectUnknownFreshness(cliPackageRoot);
138
+ if (unknown) {
139
+ console.warn(`Warning: cannot verify macf CLI dist/ freshness ` +
140
+ `(reason: ${unknown.reason}).\n` +
141
+ ` dist/.build-info.json is missing or incomplete — likely built via ` +
142
+ `\`npx tsc\` directly, skipping the canonical build path.\n` +
143
+ ` Fix: run \`cd ${cliPackageRoot} && npm run build\` to stamp build-info.\n`);
144
+ }
145
+ }
146
+ // Refresh canonical assets (coordination rules + helper scripts) on
147
+ // every `macf update`, regardless of version-pin state. These are tied
148
+ // to the installed CLI binary, not to `versions.cli` in the config —
149
+ // so a newer CLI version always wins, even when pins are unchanged.
150
+ // Running before any short-circuit also repairs workspaces created
151
+ // before these assets existed (otherwise they'd never get coordination.md
152
+ // unless the user happened to bump a pin). See #52 follow-up.
153
+ const refreshedRules = copyCanonicalRules(projectDir);
154
+ if (refreshedRules.length > 0) {
155
+ console.log(`Refreshed ${refreshedRules.length} canonical rule file(s) in .claude/rules/`);
156
+ }
157
+ const refreshedScripts = copyCanonicalScripts(projectDir);
158
+ if (refreshedScripts.length > 0) {
159
+ console.log(`Refreshed ${refreshedScripts.length} helper script(s) in .claude/scripts/`);
160
+ }
161
+ // Refresh the attribution-trap PreToolUse hook entry (merge-preserving,
162
+ // per #140). Picks up on existing workspaces + keeps the entry current
163
+ // if the CLI changes its form across releases.
164
+ installGhTokenHook(projectDir);
165
+ console.log(`Refreshed gh-token guard hook in .claude/settings.json`);
166
+ // Refresh macf-agent plugin-skill pre-approvals. Picks up new skills
167
+ // added by newer CLI versions + drops any stale patterns pointing
168
+ // at since-removed skills. See macf#189 sub-item 2.
169
+ installPluginSkillPermissions(projectDir);
170
+ console.log(`Refreshed plugin-skill permissions in .claude/settings.json`);
171
+ // Refresh sandbox.filesystem.allowRead /proc/self/fd/** entry
172
+ // (merge-preserving). Fixes every Bash tool call breaking with
173
+ // "permission denied: /proc/self/fd/3" on workspaces created
174
+ // before macf#200.
175
+ installSandboxFdAllowRead(projectDir);
176
+ console.log(`Refreshed sandbox allowRead in .claude/settings.json`);
177
+ // Regenerate claude.sh unconditionally — the launcher template changes
178
+ // over time (e.g., #60 added --plugin-dir) and workspaces need those
179
+ // changes without having to re-run `macf init` from scratch. The
180
+ // generated file carries a managed-file header warning users not to
181
+ // edit it. See #63. Doesn't depend on config.versions, so it runs even
182
+ // for legacy configs (before the error-exit for missing versions).
183
+ writeClaudeSh(projectDir, config);
184
+ console.log(`Refreshed claude.sh from current launcher template`);
185
+ // DR-011 rev2 auto-migrate: check for legacy v1 CA key backup and
186
+ // upgrade it to v2 (JSON envelope at 600k iters) if found. One-time
187
+ // per project, silent no-op if already v2 or no backup exists.
188
+ // Failures here do NOT block `macf update` — the migration is
189
+ // independent of version bumps and the v1 blob stays decryptable
190
+ // via the read-compat path. See #115.
191
+ try {
192
+ const token = await generateToken(tokenSourceFromConfig(projectDir, config));
193
+ const client = createClientFromConfig(config.registry, token);
194
+ const result = await migrateCaKeyToV2({
195
+ project: config.project,
196
+ client,
197
+ prompt: async (message) => {
198
+ try {
199
+ return await promptPassword({ message });
200
+ }
201
+ catch (err) {
202
+ if (err instanceof PromptCancelled) {
203
+ return '';
204
+ }
205
+ throw err;
206
+ }
207
+ },
208
+ });
209
+ const summary = formatMigrationResult(result, config.project);
210
+ if (summary)
211
+ console.log(summary);
212
+ }
213
+ catch (err) {
214
+ // Don't block update on migration failure (token/network/etc.).
215
+ const msg = err instanceof Error ? err.message : String(err);
216
+ console.warn(`Warning: CA key migration check failed: ${msg}`);
217
+ }
218
+ // Repair-case plugin fetch: if .macf/plugin/ is absent or empty, fetch
219
+ // the currently-pinned version regardless of whether anything is being
220
+ // bumped. Runs before every short-circuit so workspaces init'd before
221
+ // #60 merged (empty .macf/plugin/) don't require `rm -rf + macf update`
222
+ // to self-heal. See #62. We skip this if config.versions is missing —
223
+ // legacy configs are handled by the error path below.
224
+ if (config.versions && pluginDirNeedsRepair(workspacePluginDir(projectDir))) {
225
+ try {
226
+ fetchPluginToWorkspace(projectDir, config.versions.plugin);
227
+ console.log(`Repaired .macf/plugin/ with macf-agent@v${config.versions.plugin}`);
228
+ }
229
+ catch (err) {
230
+ const msg = err instanceof Error ? err.message : String(err);
231
+ console.warn(`Warning: plugin repair fetch failed: ${msg}`);
232
+ }
233
+ }
234
+ if (!config.versions) {
235
+ console.error('No "versions" section in macf-agent.json (legacy config).\n' +
236
+ 'Run `macf init --force` to migrate with resolved version pins.');
237
+ return 1;
238
+ }
239
+ console.log('Fetching latest versions...');
240
+ const resolved = await resolveLatestVersions();
241
+ const diff = buildDiff(config.versions, resolved);
242
+ console.log('');
243
+ console.log(renderDiff(diff));
244
+ console.log('');
245
+ // Exit 1 if every fetch failed (no current info to compare against).
246
+ // Any non-'update' / non-'same' status counts as failed-to-fetch here.
247
+ const FAIL_STATES = ['not_published', 'network_error', 'invalid_response'];
248
+ const allFailed = diff.every(r => FAIL_STATES.includes(r.status));
249
+ if (allFailed) {
250
+ console.error('Error: could not fetch latest versions for any component. Network down?');
251
+ return 1;
252
+ }
253
+ // Determine which components are candidates for bump.
254
+ const explicitSelection = selectedComponents(opts);
255
+ const candidates = diff.filter(row => {
256
+ if (row.status !== 'update')
257
+ return false;
258
+ if (explicitSelection.length > 0)
259
+ return explicitSelection.includes(row.component);
260
+ return true;
261
+ });
262
+ if (candidates.length === 0) {
263
+ console.log('Everything is up to date.');
264
+ return 0;
265
+ }
266
+ // Ask per candidate (or auto-accept with --yes / --all / --<component>).
267
+ const autoYes = opts.yes || opts.all || explicitSelection.length > 0;
268
+ const toBump = [];
269
+ for (const row of candidates) {
270
+ if (await confirmBump(row, autoYes)) {
271
+ toBump.push(row);
272
+ }
273
+ }
274
+ if (toBump.length === 0) {
275
+ console.log('No changes. Exiting.');
276
+ return 0;
277
+ }
278
+ // Build new versions object.
279
+ const newVersions = {
280
+ cli: config.versions.cli,
281
+ plugin: config.versions.plugin,
282
+ actions: config.versions.actions,
283
+ };
284
+ for (const row of toBump) {
285
+ newVersions[row.component] = row.latest;
286
+ }
287
+ if (opts.dryRun) {
288
+ console.log('\n[dry-run] Would update:');
289
+ for (const row of toBump) {
290
+ console.log(` ${row.component}: ${row.current} → ${row.latest}`);
291
+ }
292
+ return 0;
293
+ }
294
+ writeAgentConfig(projectDir, { ...config, versions: newVersions });
295
+ // Re-fetch the plugin when versions.plugin was bumped. The separate
296
+ // repair-case fetch runs earlier (before short-circuits) for empty/
297
+ // missing dirs; this block handles the pin-bump case specifically.
298
+ const pluginBumped = toBump.some(r => r.component === 'plugin');
299
+ if (pluginBumped) {
300
+ try {
301
+ fetchPluginToWorkspace(projectDir, newVersions.plugin);
302
+ console.log(`Refreshed .macf/plugin/ to macf-agent@v${newVersions.plugin}`);
303
+ }
304
+ catch (err) {
305
+ const msg = err instanceof Error ? err.message : String(err);
306
+ console.warn(`Warning: plugin re-fetch failed: ${msg}`);
307
+ }
308
+ }
309
+ console.log('\nUpdated:');
310
+ for (const row of toBump) {
311
+ console.log(` ✓ ${row.component}: ${row.current} → ${row.latest}`);
312
+ }
313
+ console.log('\nWritten to .macf/macf-agent.json.');
314
+ return 0;
315
+ }
316
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/cli/commands/update.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,103 @@
1
+ import { z } from 'zod';
2
+ export declare const MACF_GLOBAL_DIR: string;
3
+ export declare const AGENTS_INDEX_PATH: string;
4
+ export declare const GLOBAL_CONFIG_PATH: string;
5
+ /**
6
+ * Validate that a project name is safe for use as a filesystem directory.
7
+ * Allows alphanumeric, hyphen, underscore. Rejects slashes, dots, etc.
8
+ */
9
+ export declare function isValidProjectName(name: string): boolean;
10
+ /**
11
+ * Per-project CA directory. One subdirectory per project prevents
12
+ * collisions when multiple MACF projects share a machine.
13
+ */
14
+ export declare function caDir(project: string): string;
15
+ export declare function caCertPath(project: string): string;
16
+ export declare function caKeyPath(project: string): string;
17
+ /**
18
+ * Extract TokenSource-compatible credentials from a loaded config.
19
+ * Resolves the relative key_path against the project directory so it's
20
+ * absolute when passed to `gh token generate`.
21
+ */
22
+ export declare function tokenSourceFromConfig(projectDir: string, config: Pick<MacfAgentConfig, 'github_app'>): {
23
+ readonly appId: string;
24
+ readonly installId: string;
25
+ readonly keyPath: string;
26
+ };
27
+ /**
28
+ * Walk up from startDir looking for .macf/macf-agent.json.
29
+ * Returns the project root (the dir CONTAINING .macf/), or null if not found.
30
+ *
31
+ * Same pattern as git's discovery of .git/. Stops at the filesystem root.
32
+ */
33
+ export declare function findProjectRoot(startDir: string): string | null;
34
+ export declare function projectMacfDir(projectDir: string): string;
35
+ export declare function agentConfigPath(projectDir: string): string;
36
+ export declare function agentStatePath(projectDir: string): string;
37
+ export declare function agentCertPath(projectDir: string): string;
38
+ export declare function agentKeyPath(projectDir: string): string;
39
+ export declare function agentLogPath(projectDir: string): string;
40
+ export declare const VersionPinsSchema: z.ZodObject<{
41
+ cli: z.ZodString;
42
+ plugin: z.ZodString;
43
+ actions: z.ZodString;
44
+ }, z.core.$strip>;
45
+ export type VersionPins = z.infer<typeof VersionPinsSchema>;
46
+ export declare const MacfAgentConfigSchema: z.ZodObject<{
47
+ project: z.ZodString;
48
+ agent_name: z.ZodString;
49
+ agent_role: z.ZodString;
50
+ agent_type: z.ZodEnum<{
51
+ permanent: "permanent";
52
+ worker: "worker";
53
+ }>;
54
+ registry: z.ZodUnion<readonly [z.ZodObject<{
55
+ type: z.ZodLiteral<"org">;
56
+ org: z.ZodString;
57
+ }, z.core.$strip>, z.ZodObject<{
58
+ type: z.ZodLiteral<"profile">;
59
+ user: z.ZodString;
60
+ }, z.core.$strip>, z.ZodObject<{
61
+ type: z.ZodLiteral<"repo">;
62
+ owner: z.ZodString;
63
+ repo: z.ZodString;
64
+ }, z.core.$strip>]>;
65
+ github_app: z.ZodObject<{
66
+ app_id: z.ZodString;
67
+ install_id: z.ZodString;
68
+ key_path: z.ZodString;
69
+ }, z.core.$strip>;
70
+ advertise_host: z.ZodOptional<z.ZodString>;
71
+ tmux_session: z.ZodOptional<z.ZodString>;
72
+ tmux_window: z.ZodOptional<z.ZodString>;
73
+ versions: z.ZodOptional<z.ZodObject<{
74
+ cli: z.ZodString;
75
+ plugin: z.ZodString;
76
+ actions: z.ZodString;
77
+ }, z.core.$strip>>;
78
+ }, z.core.$strip>;
79
+ export type MacfAgentConfig = z.infer<typeof MacfAgentConfigSchema>;
80
+ export declare const AgentsIndexSchema: z.ZodObject<{
81
+ agents: z.ZodArray<z.ZodString>;
82
+ }, z.core.$strip>;
83
+ export type AgentsIndex = z.infer<typeof AgentsIndexSchema>;
84
+ export declare const GlobalConfigSchema: z.ZodObject<{
85
+ default_org: z.ZodOptional<z.ZodString>;
86
+ tailscale_hostname: z.ZodOptional<z.ZodString>;
87
+ }, z.core.$strip>;
88
+ export type GlobalConfig = z.infer<typeof GlobalConfigSchema>;
89
+ export declare function readAgentConfig(projectDir: string): MacfAgentConfig | null;
90
+ export declare function writeAgentConfig(projectDir: string, config: MacfAgentConfig): void;
91
+ export declare function readAgentsIndex(): AgentsIndex;
92
+ export declare function writeAgentsIndex(index: AgentsIndex): void;
93
+ export declare function addToAgentsIndex(projectDir: string): void;
94
+ export declare function readGlobalConfig(): GlobalConfig;
95
+ /**
96
+ * Load all agent configs from the global index.
97
+ * Skips entries with missing or invalid configs.
98
+ */
99
+ export declare function loadAllAgents(): ReadonlyArray<{
100
+ readonly path: string;
101
+ readonly config: MacfAgentConfig;
102
+ }>;
103
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,eAAO,MAAM,eAAe,QAA2B,CAAC;AACxD,eAAO,MAAM,iBAAiB,QAAuC,CAAC;AACtE,eAAO,MAAM,kBAAkB,QAAuC,CAAC;AAEvE;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD;AAUD;;;GAGG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAG7C;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,YAAY,CAAC,GAC1C;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAMlF;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAW/D;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEvD;AAKD,eAAO,MAAM,iBAAiB;;;;iBAI5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqChC,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAIpE,eAAO,MAAM,iBAAiB;;iBAE5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAI5D,eAAO,MAAM,kBAAkB;;;iBAG7B,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAS9D,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CA0B1E;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CAIlF;AAED,wBAAgB,eAAe,IAAI,WAAW,CAS7C;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAGzD;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAMzD;AAED,wBAAgB,gBAAgB,IAAI,YAAY,CAS/C;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,aAAa,CAAC;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;CAClC,CAAC,CAYD"}