@uniqbit/mate-core 0.15.4-canary.10 → 0.15.4-canary.11
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/package.json +1 -1
- package/src/cli/commands/cap/openspec.ts +20 -1
- package/src/cli/commands/companion/hub.ts +1 -0
- package/src/cli/commands/plugin/install.ts +15 -3
- package/src/lib/orchestrator/companion-hub.ts +28 -6
- package/src/lib/orchestrator/types.ts +2 -2
- package/src/templates/root/TEMPLATE_AGENTS.md +1 -1
- package/src/templates/root/TEMPLATE_CLAUDE.md +1 -1
- package/src/tools/setup/__snapshots__/runtime-surface-golden.test.ts.snap +104 -36
- package/src/tools/setup/capabilities/openspec.ts +10 -0
- package/src/tools/setup/dynamic-plugins/hydrate.ts +15 -1
- package/src/tools/setup/engine.ts +2 -0
- package/src/tools/setup/plugin.ts +4 -0
- package/src/tools/setup/providers/claude.ts +27 -8
- package/src/tools/setup/providers/opencode.ts +24 -8
- package/src/tools/setup.ts +7 -56
package/package.json
CHANGED
|
@@ -79,7 +79,26 @@ export async function runOpenspecCapCommand(
|
|
|
79
79
|
readOpenSpecProjectSchema(companionPath),
|
|
80
80
|
);
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
if (forwardedArgs[0] === "init" || forwardedArgs[0] === "update") {
|
|
83
|
+
const reset = spawnSync("openspec", ["config", "reset", "--all", "-y"], {
|
|
84
|
+
cwd,
|
|
85
|
+
stdio: "inherit",
|
|
86
|
+
});
|
|
87
|
+
if (reset.error) {
|
|
88
|
+
process.stderr.write(`Failed to reset openspec config: ${reset.error.message}\n`);
|
|
89
|
+
process.exitCode = 1;
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (reset.status !== 0) {
|
|
93
|
+
process.exitCode = reset.status ?? 1;
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const result = spawnSync("openspec", forwardedArgs, {
|
|
99
|
+
cwd,
|
|
100
|
+
stdio: "inherit",
|
|
101
|
+
});
|
|
83
102
|
if (result.error) {
|
|
84
103
|
process.stderr.write(`Failed to run openspec: ${result.error.message}\n`);
|
|
85
104
|
process.exitCode = 1;
|
|
@@ -50,6 +50,7 @@ async function selectRegisteredCompanion(): Promise<string> {
|
|
|
50
50
|
async function runHubInit(argv: string[]): Promise<void> {
|
|
51
51
|
const folder = positionalArgs(argv)[0] ?? process.cwd();
|
|
52
52
|
const hubPath = await initializeCompanionHub(folder);
|
|
53
|
+
await updateHubPlugins(hubPath);
|
|
53
54
|
console.log(`Initialized companion hub: ${hubPath}`);
|
|
54
55
|
}
|
|
55
56
|
|
|
@@ -2,8 +2,10 @@ import path from "node:path";
|
|
|
2
2
|
|
|
3
3
|
import { FRAMEWORK_NAME } from "../../../framework";
|
|
4
4
|
import { resolveInstallContext } from "../../../lib/install";
|
|
5
|
+
import { backfillHubAllowedAgents } from "../../../lib/orchestrator/companion-hub";
|
|
5
6
|
import { ConfigStore } from "../../../lib/orchestrator/config-store";
|
|
6
|
-
import type { PluginDeclaration } from "../../../lib/orchestrator/types";
|
|
7
|
+
import type { FrameworkConfig, PluginDeclaration } from "../../../lib/orchestrator/types";
|
|
8
|
+
import { applySetupCompatibilities } from "../../../tools/setup";
|
|
7
9
|
import { hydrateDynamicPlugins } from "../../../tools/setup/dynamic-plugins/hydrate";
|
|
8
10
|
import {
|
|
9
11
|
installDeclaredPlugins,
|
|
@@ -33,6 +35,7 @@ function withDeclaration(
|
|
|
33
35
|
export interface PluginInstallCommandDeps {
|
|
34
36
|
cwd?: string;
|
|
35
37
|
installDeps?: PluginInstallDeps;
|
|
38
|
+
setupHub?: (companionPath: string, config: FrameworkConfig) => Promise<void>;
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
/**
|
|
@@ -78,8 +81,10 @@ export async function runPluginInstallCommand(
|
|
|
78
81
|
);
|
|
79
82
|
const store = new ConfigStore(configPath);
|
|
80
83
|
const nextPlugins = withDeclaration(context.config.plugins ?? [], packageName, version);
|
|
81
|
-
|
|
82
|
-
|
|
84
|
+
const nextConfig = { ...context.config, plugins: nextPlugins };
|
|
85
|
+
const agentsBackfilled = context.kind === "hub" && backfillHubAllowedAgents(nextConfig);
|
|
86
|
+
if (nextPlugins !== context.config.plugins || agentsBackfilled) {
|
|
87
|
+
await store.save(nextConfig);
|
|
83
88
|
}
|
|
84
89
|
|
|
85
90
|
const results = await installDeclaredPlugins(
|
|
@@ -89,6 +94,13 @@ export async function runPluginInstallCommand(
|
|
|
89
94
|
);
|
|
90
95
|
reportPluginInstallResults(results);
|
|
91
96
|
await hydrateDynamicPlugins({ companionPath: context.companionPath });
|
|
97
|
+
if (context.kind === "hub") {
|
|
98
|
+
await (
|
|
99
|
+
deps.setupHub ??
|
|
100
|
+
((companionPath, config) =>
|
|
101
|
+
applySetupCompatibilities(companionPath, config, "sync", undefined, undefined, "hub"))
|
|
102
|
+
)(context.companionPath, nextConfig);
|
|
103
|
+
}
|
|
92
104
|
|
|
93
105
|
return results.find((result) => result.package === packageName)?.status !== "failed";
|
|
94
106
|
}
|
|
@@ -8,12 +8,14 @@ import { FRAMEWORK_NAME } from "../../framework";
|
|
|
8
8
|
import { ConfigStore, validateHubConfig } from "./config-store";
|
|
9
9
|
import { GlobalConfigStore } from "./global-config-store";
|
|
10
10
|
import type { FrameworkConfig, HubMember, HubMemberSource } from "./types";
|
|
11
|
+
import { listSetupProviderCompatibilities } from "./setup-compatibilities";
|
|
11
12
|
import {
|
|
12
13
|
installDeclaredPlugins,
|
|
13
14
|
type PluginInstallDeps,
|
|
14
15
|
type PluginInstallResult,
|
|
15
16
|
} from "../../tools/setup/dynamic-plugins/install";
|
|
16
17
|
import { hydrateDynamicPlugins } from "../../tools/setup/dynamic-plugins/hydrate";
|
|
18
|
+
import { applySetupCompatibilities } from "../../tools/setup";
|
|
17
19
|
import { findRepoLocalRegistryFile } from "./repo-local-registry";
|
|
18
20
|
|
|
19
21
|
export interface GitCommandResult {
|
|
@@ -41,6 +43,7 @@ export interface HubSyncResult {
|
|
|
41
43
|
export interface HubPluginSyncDeps {
|
|
42
44
|
installDeps?: PluginInstallDeps;
|
|
43
45
|
hydrate?: (options: { companionPath: string }) => Promise<void>;
|
|
46
|
+
setup?: (companionPath: string, config: FrameworkConfig, mode: "setup" | "sync") => Promise<void>;
|
|
44
47
|
}
|
|
45
48
|
|
|
46
49
|
export function defaultGitCommand(cwd: string, args: string[]): GitCommandResult {
|
|
@@ -123,7 +126,7 @@ export async function initializeCompanionHub(
|
|
|
123
126
|
} else {
|
|
124
127
|
const config: FrameworkConfig = {
|
|
125
128
|
type: "hub",
|
|
126
|
-
allowedAgents:
|
|
129
|
+
allowedAgents: listSetupProviderCompatibilities().map((entry) => entry.agent),
|
|
127
130
|
packageManagers: [],
|
|
128
131
|
capabilities: [],
|
|
129
132
|
hub: { companions: [] },
|
|
@@ -365,16 +368,35 @@ export async function syncHub(
|
|
|
365
368
|
return results;
|
|
366
369
|
}
|
|
367
370
|
|
|
371
|
+
/**
|
|
372
|
+
* Hubs persisted before provider bootstrapping carry `allowedAgents: []`;
|
|
373
|
+
* an empty list on a hub means "all built-in agents", not "none".
|
|
374
|
+
*/
|
|
375
|
+
export function backfillHubAllowedAgents(config: FrameworkConfig): boolean {
|
|
376
|
+
if (config.type !== "hub" || config.allowedAgents.length > 0) return false;
|
|
377
|
+
config.allowedAgents = listSetupProviderCompatibilities().map((entry) => entry.agent);
|
|
378
|
+
return true;
|
|
379
|
+
}
|
|
380
|
+
|
|
368
381
|
export async function updateHubPlugins(
|
|
369
382
|
hubPath: string,
|
|
370
383
|
deps: HubPluginSyncDeps = {},
|
|
371
384
|
): Promise<PluginInstallResult[]> {
|
|
372
|
-
const { config } = await assertHubRoot(hubPath);
|
|
385
|
+
const { config, store } = await assertHubRoot(hubPath);
|
|
386
|
+
if (backfillHubAllowedAgents(config)) await store.save(config);
|
|
373
387
|
const declarations = config.plugins ?? [];
|
|
374
|
-
if (declarations.length === 0) return [];
|
|
375
|
-
|
|
376
388
|
const resolvedHubPath = path.resolve(hubPath);
|
|
377
|
-
const results =
|
|
378
|
-
|
|
389
|
+
const results =
|
|
390
|
+
declarations.length > 0
|
|
391
|
+
? await installDeclaredPlugins(resolvedHubPath, declarations, deps.installDeps)
|
|
392
|
+
: [];
|
|
393
|
+
if (declarations.length > 0) {
|
|
394
|
+
await (deps.hydrate ?? hydrateDynamicPlugins)({ companionPath: resolvedHubPath });
|
|
395
|
+
}
|
|
396
|
+
await (
|
|
397
|
+
deps.setup ??
|
|
398
|
+
((companionPath, setupConfig, mode) =>
|
|
399
|
+
applySetupCompatibilities(companionPath, setupConfig, mode, undefined, undefined, "hub"))
|
|
400
|
+
)(resolvedHubPath, config, "sync");
|
|
379
401
|
return results;
|
|
380
402
|
}
|
|
@@ -96,8 +96,8 @@ export type PluginDeclarationPolicy = "default" | "optional";
|
|
|
96
96
|
/**
|
|
97
97
|
* A companion-declared npm plugin: installed by setup/install into the
|
|
98
98
|
* companion's own shared plugin workspace (`.mate/plugins/`) and loaded
|
|
99
|
-
* from there on every invocation. Declaration registers
|
|
100
|
-
*
|
|
99
|
+
* from there on every invocation. Declaration both registers and activates
|
|
100
|
+
* the plugin; dynamic plugins do not need a separate `capabilities` entry.
|
|
101
101
|
*/
|
|
102
102
|
export interface PluginDeclaration {
|
|
103
103
|
/** npm package name (e.g. `@acme/custom-plugin`). */
|
|
@@ -12,6 +12,6 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
12
12
|
- Code comments: JSDoc format only (`/** ... */`), never `//`. Sparse — only non-obvious invariants or constraints, never restated artifact rationale.
|
|
13
13
|
- Never add a `Co-Authored-By: <model>` trailer or model-attribution footer to commit messages.
|
|
14
14
|
- Never commit, push, or open a pull request in the working repo (`$MATE_REPO_PATH`) unless the user explicitly asks for it.
|
|
15
|
-
- Never
|
|
15
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
16
16
|
|
|
17
17
|
<!-- MATE:COMPANION:END -->
|
|
@@ -14,6 +14,6 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
14
14
|
- The root `CLAUDE.md` in the companion repo is intentional and loaded by Mate. Do not create another project-level `CLAUDE.md` in the working repo unless the user explicitly asks for one.
|
|
15
15
|
- Never add a `Co-Authored-By: <model>` trailer or model-attribution footer to commit messages.
|
|
16
16
|
- Never commit, push, or open a pull request in the working repo (`$MATE_REPO_PATH`) unless the user explicitly asks for it.
|
|
17
|
-
- Never
|
|
17
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
18
18
|
|
|
19
19
|
<!-- MATE:COMPANION:END -->
|
|
@@ -17,6 +17,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
17
17
|
- Code comments: JSDoc format only (\`/** ... */\`), never \`//\`. Sparse — only non-obvious invariants or constraints, never restated artifact rationale.
|
|
18
18
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
19
19
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
20
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
20
21
|
|
|
21
22
|
<!-- MATE:COMPANION:END -->
|
|
22
23
|
"
|
|
@@ -42,6 +43,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
42
43
|
- The root \`CLAUDE.md\` in the companion repo is intentional and loaded by Mate. Do not create another project-level \`CLAUDE.md\` in the working repo unless the user explicitly asks for one.
|
|
43
44
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
44
45
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
46
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
45
47
|
|
|
46
48
|
<!-- MATE:COMPANION:END -->
|
|
47
49
|
"
|
|
@@ -174,6 +176,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
174
176
|
- Code comments: JSDoc format only (\`/** ... */\`), never \`//\`. Sparse — only non-obvious invariants or constraints, never restated artifact rationale.
|
|
175
177
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
176
178
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
179
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
177
180
|
|
|
178
181
|
<!-- MATE:COMPANION:END -->
|
|
179
182
|
"
|
|
@@ -191,7 +194,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
191
194
|
"reserved": 15000,
|
|
192
195
|
},
|
|
193
196
|
"plugin": [
|
|
194
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
197
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
195
198
|
],
|
|
196
199
|
"references": {
|
|
197
200
|
"mate": "..",
|
|
@@ -227,7 +230,7 @@ Write chunks to $GRAPHIFY_OUT and read $GRAPHIFY_OUT later.
|
|
|
227
230
|
"opencodeTui": {
|
|
228
231
|
"$schema": "https://opencode.ai/tui.json",
|
|
229
232
|
"plugin": [
|
|
230
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
233
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
231
234
|
],
|
|
232
235
|
},
|
|
233
236
|
}
|
|
@@ -321,6 +324,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
321
324
|
- Code comments: JSDoc format only (\`/** ... */\`), never \`//\`. Sparse — only non-obvious invariants or constraints, never restated artifact rationale.
|
|
322
325
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
323
326
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
327
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
324
328
|
|
|
325
329
|
<!-- MATE:COMPANION:END -->
|
|
326
330
|
"
|
|
@@ -346,6 +350,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
346
350
|
- The root \`CLAUDE.md\` in the companion repo is intentional and loaded by Mate. Do not create another project-level \`CLAUDE.md\` in the working repo unless the user explicitly asks for one.
|
|
347
351
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
348
352
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
353
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
349
354
|
|
|
350
355
|
<!-- MATE:COMPANION:END -->
|
|
351
356
|
"
|
|
@@ -402,7 +407,7 @@ Write chunks to $GRAPHIFY_OUT and read $GRAPHIFY_OUT later.
|
|
|
402
407
|
"reserved": 15000,
|
|
403
408
|
},
|
|
404
409
|
"plugin": [
|
|
405
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
410
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
406
411
|
],
|
|
407
412
|
"references": {
|
|
408
413
|
"mate": "..",
|
|
@@ -438,7 +443,7 @@ Write chunks to $GRAPHIFY_OUT and read $GRAPHIFY_OUT later.
|
|
|
438
443
|
"opencodeTui": {
|
|
439
444
|
"$schema": "https://opencode.ai/tui.json",
|
|
440
445
|
"plugin": [
|
|
441
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
446
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
442
447
|
],
|
|
443
448
|
},
|
|
444
449
|
}
|
|
@@ -587,6 +592,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
587
592
|
- Code comments: JSDoc format only (\`/** ... */\`), never \`//\`. Sparse — only non-obvious invariants or constraints, never restated artifact rationale.
|
|
588
593
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
589
594
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
595
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
590
596
|
|
|
591
597
|
<!-- MATE:COMPANION:END -->
|
|
592
598
|
"
|
|
@@ -619,6 +625,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
619
625
|
- The root \`CLAUDE.md\` in the companion repo is intentional and loaded by Mate. Do not create another project-level \`CLAUDE.md\` in the working repo unless the user explicitly asks for one.
|
|
620
626
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
621
627
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
628
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
622
629
|
|
|
623
630
|
<!-- MATE:COMPANION:END -->
|
|
624
631
|
"
|
|
@@ -758,6 +765,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
758
765
|
- Code comments: JSDoc format only (\`/** ... */\`), never \`//\`. Sparse — only non-obvious invariants or constraints, never restated artifact rationale.
|
|
759
766
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
760
767
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
768
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
761
769
|
|
|
762
770
|
<!-- MATE:COMPANION:END -->
|
|
763
771
|
"
|
|
@@ -785,7 +793,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
785
793
|
},
|
|
786
794
|
},
|
|
787
795
|
"plugin": [
|
|
788
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
796
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
789
797
|
],
|
|
790
798
|
"references": {
|
|
791
799
|
"mate": "..",
|
|
@@ -800,7 +808,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
800
808
|
"opencodeTui": {
|
|
801
809
|
"$schema": "https://opencode.ai/tui.json",
|
|
802
810
|
"plugin": [
|
|
803
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
811
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
804
812
|
],
|
|
805
813
|
},
|
|
806
814
|
}
|
|
@@ -891,6 +899,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
891
899
|
- Code comments: JSDoc format only (\`/** ... */\`), never \`//\`. Sparse — only non-obvious invariants or constraints, never restated artifact rationale.
|
|
892
900
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
893
901
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
902
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
894
903
|
|
|
895
904
|
<!-- MATE:COMPANION:END -->
|
|
896
905
|
"
|
|
@@ -923,6 +932,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
923
932
|
- The root \`CLAUDE.md\` in the companion repo is intentional and loaded by Mate. Do not create another project-level \`CLAUDE.md\` in the working repo unless the user explicitly asks for one.
|
|
924
933
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
925
934
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
935
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
926
936
|
|
|
927
937
|
<!-- MATE:COMPANION:END -->
|
|
928
938
|
"
|
|
@@ -999,7 +1009,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
999
1009
|
},
|
|
1000
1010
|
},
|
|
1001
1011
|
"plugin": [
|
|
1002
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
1012
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
1003
1013
|
],
|
|
1004
1014
|
"references": {
|
|
1005
1015
|
"mate": "..",
|
|
@@ -1014,7 +1024,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
1014
1024
|
"opencodeTui": {
|
|
1015
1025
|
"$schema": "https://opencode.ai/tui.json",
|
|
1016
1026
|
"plugin": [
|
|
1017
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
1027
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
1018
1028
|
],
|
|
1019
1029
|
},
|
|
1020
1030
|
}
|
|
@@ -1157,6 +1167,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
1157
1167
|
- Code comments: JSDoc format only (\`/** ... */\`), never \`//\`. Sparse — only non-obvious invariants or constraints, never restated artifact rationale.
|
|
1158
1168
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
1159
1169
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
1170
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
1160
1171
|
|
|
1161
1172
|
<!-- MATE:COMPANION:END -->
|
|
1162
1173
|
"
|
|
@@ -1182,6 +1193,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
1182
1193
|
- The root \`CLAUDE.md\` in the companion repo is intentional and loaded by Mate. Do not create another project-level \`CLAUDE.md\` in the working repo unless the user explicitly asks for one.
|
|
1183
1194
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
1184
1195
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
1196
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
1185
1197
|
|
|
1186
1198
|
<!-- MATE:COMPANION:END -->
|
|
1187
1199
|
"
|
|
@@ -1274,6 +1286,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
1274
1286
|
- Code comments: JSDoc format only (\`/** ... */\`), never \`//\`. Sparse — only non-obvious invariants or constraints, never restated artifact rationale.
|
|
1275
1287
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
1276
1288
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
1289
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
1277
1290
|
|
|
1278
1291
|
<!-- MATE:COMPANION:END -->
|
|
1279
1292
|
|
|
@@ -1299,7 +1312,7 @@ Canonical Mate policy and any more specific tool-routing instructions remain aut
|
|
|
1299
1312
|
"reserved": 15000,
|
|
1300
1313
|
},
|
|
1301
1314
|
"plugin": [
|
|
1302
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
1315
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
1303
1316
|
"context-mode@1.0.169",
|
|
1304
1317
|
],
|
|
1305
1318
|
"references": {
|
|
@@ -1315,7 +1328,7 @@ Canonical Mate policy and any more specific tool-routing instructions remain aut
|
|
|
1315
1328
|
"opencodeTui": {
|
|
1316
1329
|
"$schema": "https://opencode.ai/tui.json",
|
|
1317
1330
|
"plugin": [
|
|
1318
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
1331
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
1319
1332
|
"context-mode@1.0.169",
|
|
1320
1333
|
],
|
|
1321
1334
|
},
|
|
@@ -1399,6 +1412,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
1399
1412
|
- Code comments: JSDoc format only (\`/** ... */\`), never \`//\`. Sparse — only non-obvious invariants or constraints, never restated artifact rationale.
|
|
1400
1413
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
1401
1414
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
1415
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
1402
1416
|
|
|
1403
1417
|
<!-- MATE:COMPANION:END -->
|
|
1404
1418
|
|
|
@@ -1432,6 +1446,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
1432
1446
|
- The root \`CLAUDE.md\` in the companion repo is intentional and loaded by Mate. Do not create another project-level \`CLAUDE.md\` in the working repo unless the user explicitly asks for one.
|
|
1433
1447
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
1434
1448
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
1449
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
1435
1450
|
|
|
1436
1451
|
<!-- MATE:COMPANION:END -->
|
|
1437
1452
|
"
|
|
@@ -1457,7 +1472,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
1457
1472
|
"reserved": 15000,
|
|
1458
1473
|
},
|
|
1459
1474
|
"plugin": [
|
|
1460
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
1475
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
1461
1476
|
"context-mode@1.0.169",
|
|
1462
1477
|
],
|
|
1463
1478
|
"references": {
|
|
@@ -1473,7 +1488,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
1473
1488
|
"opencodeTui": {
|
|
1474
1489
|
"$schema": "https://opencode.ai/tui.json",
|
|
1475
1490
|
"plugin": [
|
|
1476
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
1491
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
1477
1492
|
"context-mode@1.0.169",
|
|
1478
1493
|
],
|
|
1479
1494
|
},
|
|
@@ -1603,6 +1618,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
1603
1618
|
- Code comments: JSDoc format only (\`/** ... */\`), never \`//\`. Sparse — only non-obvious invariants or constraints, never restated artifact rationale.
|
|
1604
1619
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
1605
1620
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
1621
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
1606
1622
|
|
|
1607
1623
|
<!-- MATE:COMPANION:END -->
|
|
1608
1624
|
"
|
|
@@ -1630,6 +1646,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
1630
1646
|
- The root \`CLAUDE.md\` in the companion repo is intentional and loaded by Mate. Do not create another project-level \`CLAUDE.md\` in the working repo unless the user explicitly asks for one.
|
|
1631
1647
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
1632
1648
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
1649
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
1633
1650
|
|
|
1634
1651
|
<!-- MATE:COMPANION:END -->
|
|
1635
1652
|
"
|
|
@@ -1749,6 +1766,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
1749
1766
|
- Code comments: JSDoc format only (\`/** ... */\`), never \`//\`. Sparse — only non-obvious invariants or constraints, never restated artifact rationale.
|
|
1750
1767
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
1751
1768
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
1769
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
1752
1770
|
|
|
1753
1771
|
<!-- MATE:COMPANION:END -->
|
|
1754
1772
|
"
|
|
@@ -1766,7 +1784,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
1766
1784
|
"reserved": 15000,
|
|
1767
1785
|
},
|
|
1768
1786
|
"plugin": [
|
|
1769
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
1787
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
1770
1788
|
],
|
|
1771
1789
|
"references": {
|
|
1772
1790
|
"mate": "..",
|
|
@@ -1784,7 +1802,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
1784
1802
|
"opencodeTui": {
|
|
1785
1803
|
"$schema": "https://opencode.ai/tui.json",
|
|
1786
1804
|
"plugin": [
|
|
1787
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
1805
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
1788
1806
|
],
|
|
1789
1807
|
},
|
|
1790
1808
|
}
|
|
@@ -1867,6 +1885,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
1867
1885
|
- Code comments: JSDoc format only (\`/** ... */\`), never \`//\`. Sparse — only non-obvious invariants or constraints, never restated artifact rationale.
|
|
1868
1886
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
1869
1887
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
1888
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
1870
1889
|
|
|
1871
1890
|
<!-- MATE:COMPANION:END -->
|
|
1872
1891
|
"
|
|
@@ -1894,6 +1913,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
1894
1913
|
- The root \`CLAUDE.md\` in the companion repo is intentional and loaded by Mate. Do not create another project-level \`CLAUDE.md\` in the working repo unless the user explicitly asks for one.
|
|
1895
1914
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
1896
1915
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
1916
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
1897
1917
|
|
|
1898
1918
|
<!-- MATE:COMPANION:END -->
|
|
1899
1919
|
"
|
|
@@ -1948,7 +1968,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
1948
1968
|
"reserved": 15000,
|
|
1949
1969
|
},
|
|
1950
1970
|
"plugin": [
|
|
1951
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
1971
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
1952
1972
|
],
|
|
1953
1973
|
"references": {
|
|
1954
1974
|
"mate": "..",
|
|
@@ -1966,7 +1986,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
1966
1986
|
"opencodeTui": {
|
|
1967
1987
|
"$schema": "https://opencode.ai/tui.json",
|
|
1968
1988
|
"plugin": [
|
|
1969
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
1989
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
1970
1990
|
],
|
|
1971
1991
|
},
|
|
1972
1992
|
}
|
|
@@ -2093,6 +2113,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
2093
2113
|
- Code comments: JSDoc format only (\`/** ... */\`), never \`//\`. Sparse — only non-obvious invariants or constraints, never restated artifact rationale.
|
|
2094
2114
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
2095
2115
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
2116
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
2096
2117
|
|
|
2097
2118
|
<!-- MATE:COMPANION:END -->
|
|
2098
2119
|
"
|
|
@@ -2118,6 +2139,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
2118
2139
|
- The root \`CLAUDE.md\` in the companion repo is intentional and loaded by Mate. Do not create another project-level \`CLAUDE.md\` in the working repo unless the user explicitly asks for one.
|
|
2119
2140
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
2120
2141
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
2142
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
2121
2143
|
|
|
2122
2144
|
<!-- MATE:COMPANION:END -->
|
|
2123
2145
|
"
|
|
@@ -2220,6 +2242,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
2220
2242
|
- Code comments: JSDoc format only (\`/** ... */\`), never \`//\`. Sparse — only non-obvious invariants or constraints, never restated artifact rationale.
|
|
2221
2243
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
2222
2244
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
2245
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
2223
2246
|
|
|
2224
2247
|
<!-- MATE:COMPANION:END -->
|
|
2225
2248
|
"
|
|
@@ -2237,7 +2260,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
2237
2260
|
"reserved": 15000,
|
|
2238
2261
|
},
|
|
2239
2262
|
"plugin": [
|
|
2240
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
2263
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
2241
2264
|
],
|
|
2242
2265
|
"references": {
|
|
2243
2266
|
"mate": "..",
|
|
@@ -2257,7 +2280,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
2257
2280
|
"opencodeTui": {
|
|
2258
2281
|
"$schema": "https://opencode.ai/tui.json",
|
|
2259
2282
|
"plugin": [
|
|
2260
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
2283
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
2261
2284
|
],
|
|
2262
2285
|
},
|
|
2263
2286
|
}
|
|
@@ -2341,6 +2364,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
2341
2364
|
- Code comments: JSDoc format only (\`/** ... */\`), never \`//\`. Sparse — only non-obvious invariants or constraints, never restated artifact rationale.
|
|
2342
2365
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
2343
2366
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
2367
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
2344
2368
|
|
|
2345
2369
|
<!-- MATE:COMPANION:END -->
|
|
2346
2370
|
"
|
|
@@ -2366,6 +2390,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
2366
2390
|
- The root \`CLAUDE.md\` in the companion repo is intentional and loaded by Mate. Do not create another project-level \`CLAUDE.md\` in the working repo unless the user explicitly asks for one.
|
|
2367
2391
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
2368
2392
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
2393
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
2369
2394
|
|
|
2370
2395
|
<!-- MATE:COMPANION:END -->
|
|
2371
2396
|
"
|
|
@@ -2402,7 +2427,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
2402
2427
|
"reserved": 15000,
|
|
2403
2428
|
},
|
|
2404
2429
|
"plugin": [
|
|
2405
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
2430
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
2406
2431
|
],
|
|
2407
2432
|
"references": {
|
|
2408
2433
|
"mate": "..",
|
|
@@ -2422,7 +2447,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
2422
2447
|
"opencodeTui": {
|
|
2423
2448
|
"$schema": "https://opencode.ai/tui.json",
|
|
2424
2449
|
"plugin": [
|
|
2425
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
2450
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
2426
2451
|
],
|
|
2427
2452
|
},
|
|
2428
2453
|
}
|
|
@@ -2551,6 +2576,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
2551
2576
|
- Code comments: JSDoc format only (\`/** ... */\`), never \`//\`. Sparse — only non-obvious invariants or constraints, never restated artifact rationale.
|
|
2552
2577
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
2553
2578
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
2579
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
2554
2580
|
|
|
2555
2581
|
<!-- MATE:COMPANION:END -->
|
|
2556
2582
|
|
|
@@ -2593,6 +2619,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
2593
2619
|
- The root \`CLAUDE.md\` in the companion repo is intentional and loaded by Mate. Do not create another project-level \`CLAUDE.md\` in the working repo unless the user explicitly asks for one.
|
|
2594
2620
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
2595
2621
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
2622
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
2596
2623
|
|
|
2597
2624
|
<!-- MATE:COMPANION:END -->
|
|
2598
2625
|
"
|
|
@@ -2738,7 +2765,7 @@ Write chunks to $GRAPHIFY_OUT and read $GRAPHIFY_OUT later.
|
|
|
2738
2765
|
},
|
|
2739
2766
|
},
|
|
2740
2767
|
"plugin": [
|
|
2741
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
2768
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
2742
2769
|
"context-mode@1.0.169",
|
|
2743
2770
|
],
|
|
2744
2771
|
"references": {
|
|
@@ -2781,7 +2808,7 @@ Write chunks to $GRAPHIFY_OUT and read $GRAPHIFY_OUT later.
|
|
|
2781
2808
|
"opencodeTui": {
|
|
2782
2809
|
"$schema": "https://opencode.ai/tui.json",
|
|
2783
2810
|
"plugin": [
|
|
2784
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
2811
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
2785
2812
|
"context-mode@1.0.169",
|
|
2786
2813
|
],
|
|
2787
2814
|
},
|
|
@@ -2935,6 +2962,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
2935
2962
|
- Code comments: JSDoc format only (\`/** ... */\`), never \`//\`. Sparse — only non-obvious invariants or constraints, never restated artifact rationale.
|
|
2936
2963
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
2937
2964
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
2965
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
2938
2966
|
|
|
2939
2967
|
<!-- MATE:COMPANION:END -->
|
|
2940
2968
|
"
|
|
@@ -2960,6 +2988,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
2960
2988
|
- The root \`CLAUDE.md\` in the companion repo is intentional and loaded by Mate. Do not create another project-level \`CLAUDE.md\` in the working repo unless the user explicitly asks for one.
|
|
2961
2989
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
2962
2990
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
2991
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
2963
2992
|
|
|
2964
2993
|
<!-- MATE:COMPANION:END -->
|
|
2965
2994
|
"
|
|
@@ -2983,7 +3012,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
2983
3012
|
"reserved": 15000,
|
|
2984
3013
|
},
|
|
2985
3014
|
"plugin": [
|
|
2986
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
3015
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
2987
3016
|
],
|
|
2988
3017
|
"references": {
|
|
2989
3018
|
"mate": "..",
|
|
@@ -2998,7 +3027,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
2998
3027
|
"opencodeTui": {
|
|
2999
3028
|
"$schema": "https://opencode.ai/tui.json",
|
|
3000
3029
|
"plugin": [
|
|
3001
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
3030
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
3002
3031
|
],
|
|
3003
3032
|
},
|
|
3004
3033
|
}
|
|
@@ -3021,6 +3050,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
3021
3050
|
- Code comments: JSDoc format only (\`/** ... */\`), never \`//\`. Sparse — only non-obvious invariants or constraints, never restated artifact rationale.
|
|
3022
3051
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
3023
3052
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
3053
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
3024
3054
|
|
|
3025
3055
|
<!-- MATE:COMPANION:END -->
|
|
3026
3056
|
"
|
|
@@ -3046,6 +3076,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
3046
3076
|
- The root \`CLAUDE.md\` in the companion repo is intentional and loaded by Mate. Do not create another project-level \`CLAUDE.md\` in the working repo unless the user explicitly asks for one.
|
|
3047
3077
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
3048
3078
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
3079
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
3049
3080
|
|
|
3050
3081
|
<!-- MATE:COMPANION:END -->
|
|
3051
3082
|
"
|
|
@@ -3069,7 +3100,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
3069
3100
|
"reserved": 15000,
|
|
3070
3101
|
},
|
|
3071
3102
|
"plugin": [
|
|
3072
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
3103
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
3073
3104
|
],
|
|
3074
3105
|
"references": {
|
|
3075
3106
|
"mate": "..",
|
|
@@ -3084,7 +3115,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
3084
3115
|
"opencodeTui": {
|
|
3085
3116
|
"$schema": "https://opencode.ai/tui.json",
|
|
3086
3117
|
"plugin": [
|
|
3087
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
3118
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
3088
3119
|
],
|
|
3089
3120
|
},
|
|
3090
3121
|
}
|
|
@@ -3107,6 +3138,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
3107
3138
|
- Code comments: JSDoc format only (\`/** ... */\`), never \`//\`. Sparse — only non-obvious invariants or constraints, never restated artifact rationale.
|
|
3108
3139
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
3109
3140
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
3141
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
3110
3142
|
|
|
3111
3143
|
<!-- MATE:COMPANION:END -->
|
|
3112
3144
|
|
|
@@ -3133,6 +3165,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
3133
3165
|
- The root \`CLAUDE.md\` in the companion repo is intentional and loaded by Mate. Do not create another project-level \`CLAUDE.md\` in the working repo unless the user explicitly asks for one.
|
|
3134
3166
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
3135
3167
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
3168
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
3136
3169
|
|
|
3137
3170
|
<!-- MATE:COMPANION:END -->
|
|
3138
3171
|
"
|
|
@@ -3156,7 +3189,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
3156
3189
|
"reserved": 15000,
|
|
3157
3190
|
},
|
|
3158
3191
|
"plugin": [
|
|
3159
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
3192
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
3160
3193
|
],
|
|
3161
3194
|
"references": {
|
|
3162
3195
|
"mate": "..",
|
|
@@ -3171,7 +3204,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
3171
3204
|
"opencodeTui": {
|
|
3172
3205
|
"$schema": "https://opencode.ai/tui.json",
|
|
3173
3206
|
"plugin": [
|
|
3174
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
3207
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
3175
3208
|
],
|
|
3176
3209
|
},
|
|
3177
3210
|
}
|
|
@@ -3194,6 +3227,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
3194
3227
|
- Code comments: JSDoc format only (\`/** ... */\`), never \`//\`. Sparse — only non-obvious invariants or constraints, never restated artifact rationale.
|
|
3195
3228
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
3196
3229
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
3230
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
3197
3231
|
|
|
3198
3232
|
<!-- MATE:COMPANION:END -->
|
|
3199
3233
|
"
|
|
@@ -3219,6 +3253,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
3219
3253
|
- The root \`CLAUDE.md\` in the companion repo is intentional and loaded by Mate. Do not create another project-level \`CLAUDE.md\` in the working repo unless the user explicitly asks for one.
|
|
3220
3254
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
3221
3255
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
3256
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
3222
3257
|
|
|
3223
3258
|
<!-- MATE:COMPANION:END -->
|
|
3224
3259
|
"
|
|
@@ -3242,7 +3277,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
3242
3277
|
"reserved": 15000,
|
|
3243
3278
|
},
|
|
3244
3279
|
"plugin": [
|
|
3245
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
3280
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
3246
3281
|
],
|
|
3247
3282
|
"references": {
|
|
3248
3283
|
"mate": "..",
|
|
@@ -3257,7 +3292,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
3257
3292
|
"opencodeTui": {
|
|
3258
3293
|
"$schema": "https://opencode.ai/tui.json",
|
|
3259
3294
|
"plugin": [
|
|
3260
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
3295
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
3261
3296
|
],
|
|
3262
3297
|
},
|
|
3263
3298
|
}
|
|
@@ -3280,6 +3315,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
3280
3315
|
- Code comments: JSDoc format only (\`/** ... */\`), never \`//\`. Sparse — only non-obvious invariants or constraints, never restated artifact rationale.
|
|
3281
3316
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
3282
3317
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
3318
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
3283
3319
|
|
|
3284
3320
|
<!-- MATE:COMPANION:END -->
|
|
3285
3321
|
"
|
|
@@ -3305,6 +3341,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
3305
3341
|
- The root \`CLAUDE.md\` in the companion repo is intentional and loaded by Mate. Do not create another project-level \`CLAUDE.md\` in the working repo unless the user explicitly asks for one.
|
|
3306
3342
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
3307
3343
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
3344
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
3308
3345
|
|
|
3309
3346
|
<!-- MATE:COMPANION:END -->
|
|
3310
3347
|
"
|
|
@@ -3328,7 +3365,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
3328
3365
|
"reserved": 15000,
|
|
3329
3366
|
},
|
|
3330
3367
|
"plugin": [
|
|
3331
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
3368
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
3332
3369
|
],
|
|
3333
3370
|
"references": {
|
|
3334
3371
|
"mate": "..",
|
|
@@ -3343,7 +3380,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
3343
3380
|
"opencodeTui": {
|
|
3344
3381
|
"$schema": "https://opencode.ai/tui.json",
|
|
3345
3382
|
"plugin": [
|
|
3346
|
-
"@uniqbit/mate-opencode-plugin@0.15.4-canary.
|
|
3383
|
+
"@uniqbit/mate-opencode-plugin@0.15.4-canary.10",
|
|
3347
3384
|
],
|
|
3348
3385
|
},
|
|
3349
3386
|
}
|
|
@@ -3366,6 +3403,7 @@ This block is kept for AGENTS.md compatibility and must not restate that policy.
|
|
|
3366
3403
|
- Code comments: JSDoc format only (\`/** ... */\`), never \`//\`. Sparse — only non-obvious invariants or constraints, never restated artifact rationale.
|
|
3367
3404
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
3368
3405
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
3406
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
3369
3407
|
|
|
3370
3408
|
<!-- MATE:COMPANION:END -->
|
|
3371
3409
|
"
|
|
@@ -3391,6 +3429,7 @@ This block is kept for Claude/AGENTS.md compatibility and must not restate that
|
|
|
3391
3429
|
- The root \`CLAUDE.md\` in the companion repo is intentional and loaded by Mate. Do not create another project-level \`CLAUDE.md\` in the working repo unless the user explicitly asks for one.
|
|
3392
3430
|
- Never add a \`Co-Authored-By: <model>\` trailer or model-attribution footer to commit messages.
|
|
3393
3431
|
- Never commit, push, or open a pull request in the working repo (\`$MATE_REPO_PATH\`) unless the user explicitly asks for it.
|
|
3432
|
+
- Never connect to a database (local or remote), touch live/external systems (deploys, infra), or take destructive/irreversible actions without asking the user first.
|
|
3394
3433
|
|
|
3395
3434
|
<!-- MATE:COMPANION:END -->
|
|
3396
3435
|
"
|
|
@@ -3525,15 +3564,44 @@ User notes.
|
|
|
3525
3564
|
}
|
|
3526
3565
|
`;
|
|
3527
3566
|
|
|
3528
|
-
exports[`working repo golden fixtures hub roots
|
|
3567
|
+
exports[`working repo golden fixtures hub roots set up providers only without companion surfaces 1`] = `
|
|
3529
3568
|
{
|
|
3530
3569
|
"agentsMd": null,
|
|
3531
3570
|
"claudeHooks": {},
|
|
3532
|
-
"claudeMcpConfig":
|
|
3571
|
+
"claudeMcpConfig": {
|
|
3572
|
+
"mcpServers": {
|
|
3573
|
+
"tokensave": {
|
|
3574
|
+
"args": [
|
|
3575
|
+
"serve",
|
|
3576
|
+
],
|
|
3577
|
+
"command": "tokensave",
|
|
3578
|
+
},
|
|
3579
|
+
},
|
|
3580
|
+
},
|
|
3533
3581
|
"claudeMd": null,
|
|
3534
|
-
"claudeSettingsLocal":
|
|
3582
|
+
"claudeSettingsLocal": {
|
|
3583
|
+
"autoMemoryEnabled": false,
|
|
3584
|
+
"permissions": {
|
|
3585
|
+
"allow": [
|
|
3586
|
+
"Bash(mate:*)",
|
|
3587
|
+
"Edit(<root>/companion/**)",
|
|
3588
|
+
"Read(<root>/companion/**)",
|
|
3589
|
+
],
|
|
3590
|
+
},
|
|
3591
|
+
},
|
|
3535
3592
|
"claudeSkills": {},
|
|
3536
|
-
"opencodeConfig":
|
|
3593
|
+
"opencodeConfig": {
|
|
3594
|
+
"mcp": {
|
|
3595
|
+
"tokensave": {
|
|
3596
|
+
"command": [
|
|
3597
|
+
"tokensave",
|
|
3598
|
+
"serve",
|
|
3599
|
+
],
|
|
3600
|
+
"enabled": true,
|
|
3601
|
+
"type": "local",
|
|
3602
|
+
},
|
|
3603
|
+
},
|
|
3604
|
+
},
|
|
3537
3605
|
"opencodePlugins": {},
|
|
3538
3606
|
"opencodeSkills": {},
|
|
3539
3607
|
"opencodeTui": null,
|
|
@@ -134,6 +134,16 @@ async function reconcileOpenSpecTools(
|
|
|
134
134
|
): Promise<void> {
|
|
135
135
|
const tools = deriveOpenSpecTools(ctx.activeProviders);
|
|
136
136
|
if (tools.length === 0) return;
|
|
137
|
+
/** Best-effort: `config reset` is missing on older openspec releases. */
|
|
138
|
+
try {
|
|
139
|
+
await runCommand("openspec", ["config", "reset", "--all", "-y"], {
|
|
140
|
+
cwd: ctx.companionPath,
|
|
141
|
+
});
|
|
142
|
+
} catch (error) {
|
|
143
|
+
process.stderr.write(
|
|
144
|
+
`openspec config reset skipped: ${error instanceof Error ? error.message : String(error)}\n`,
|
|
145
|
+
);
|
|
146
|
+
}
|
|
137
147
|
|
|
138
148
|
await runCommand("openspec", ["init", "--tools", tools.join(","), "--force", ctx.companionPath], {
|
|
139
149
|
cwd: ctx.companionPath,
|
|
@@ -9,6 +9,7 @@ import { CompanionResolver } from "../../../lib/orchestrator/companion-resolver"
|
|
|
9
9
|
import { GlobalConfigStore } from "../../../lib/orchestrator/global-config-store";
|
|
10
10
|
import { PLUGIN_DECLARATION_POLICIES } from "../../../lib/orchestrator/config-store";
|
|
11
11
|
import type { PluginDeclaration } from "../../../lib/orchestrator/types";
|
|
12
|
+
import type { Plugin } from "../plugin";
|
|
12
13
|
import type { PluginRegistry } from "../registry";
|
|
13
14
|
import { loadDynamicPlugin, type DynamicPluginLoadDeps } from "./loader";
|
|
14
15
|
|
|
@@ -89,6 +90,16 @@ function validateDeclaration(entry: unknown): { declaration?: PluginDeclaration;
|
|
|
89
90
|
return { declaration: entry as unknown as PluginDeclaration };
|
|
90
91
|
}
|
|
91
92
|
|
|
93
|
+
/**
|
|
94
|
+
* A framework declaration is the activation switch for a dynamic plugin.
|
|
95
|
+
* Own-property override rather than a spread: class-instance plugins keep
|
|
96
|
+
* their prototype members.
|
|
97
|
+
*/
|
|
98
|
+
function activateDeclaredPlugin(plugin: Plugin): Plugin {
|
|
99
|
+
plugin.isEnabled = () => true;
|
|
100
|
+
return plugin;
|
|
101
|
+
}
|
|
102
|
+
|
|
92
103
|
/**
|
|
93
104
|
* Registers the companion's declared plugins into the active registry —
|
|
94
105
|
* compiled-in plugins first (they are already registered), declared order
|
|
@@ -135,7 +146,10 @@ export async function hydrateDynamicPlugins(deps: HydrateDynamicPluginsDeps = {}
|
|
|
135
146
|
);
|
|
136
147
|
}
|
|
137
148
|
|
|
138
|
-
registry.register({
|
|
149
|
+
registry.register({
|
|
150
|
+
plugin: activateDeclaredPlugin(result.plugin),
|
|
151
|
+
policy: declaration.policy ?? "optional",
|
|
152
|
+
});
|
|
139
153
|
hydratedPackages.add(declaration.package);
|
|
140
154
|
}
|
|
141
155
|
} catch (error) {
|
|
@@ -125,6 +125,8 @@ export async function executeSetupInstallationPlan(
|
|
|
125
125
|
});
|
|
126
126
|
|
|
127
127
|
for (const action of plan.actions) {
|
|
128
|
+
if (ctx.scope === "hub" && action.phase !== "provider") continue;
|
|
129
|
+
|
|
128
130
|
const plugin = pluginById.get(action.pluginId);
|
|
129
131
|
if (!plugin) {
|
|
130
132
|
continue;
|
|
@@ -2,11 +2,15 @@ import type { FrameworkConfig, LinkedRepository } from "../../lib/orchestrator/t
|
|
|
2
2
|
import type { InstallRequirement, InstallRequirementContext } from "./install-contract";
|
|
3
3
|
import type { ClaudeHookGroup } from "./providers/claude-format";
|
|
4
4
|
|
|
5
|
+
export type SetupScope = "companion" | "hub";
|
|
6
|
+
|
|
5
7
|
export interface SetupContext {
|
|
6
8
|
companionPath: string;
|
|
7
9
|
config: FrameworkConfig;
|
|
8
10
|
mode: "setup" | "sync";
|
|
9
11
|
activeProviders: string[];
|
|
12
|
+
/** Hub setup runs providers but excludes companion-only surfaces. */
|
|
13
|
+
scope?: SetupScope;
|
|
10
14
|
/** Working repository path when syncing from a linked repo (e.g. during launch). */
|
|
11
15
|
repoPath?: string;
|
|
12
16
|
/**
|
|
@@ -346,6 +346,11 @@ export async function reconcileClaudeContributions(
|
|
|
346
346
|
): Promise<void> {
|
|
347
347
|
const { companionPath, config } = ctx;
|
|
348
348
|
|
|
349
|
+
if (ctx.scope === "hub") {
|
|
350
|
+
await reconcileClaudeMcpContributions(ctx, inputs);
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
|
|
349
354
|
// The settings sync (re)creates the managed settings document, so it only
|
|
350
355
|
// runs while the Claude runtime is active; a deactivated runtime's pass is
|
|
351
356
|
// teardown-only and must not resurrect files the provider teardown removed.
|
|
@@ -353,15 +358,9 @@ export async function reconcileClaudeContributions(
|
|
|
353
358
|
await syncCompanionClaudeSettings(companionPath, config, inputs);
|
|
354
359
|
}
|
|
355
360
|
|
|
356
|
-
|
|
357
|
-
for (const descriptor of input.contributions.mcpServers ?? []) {
|
|
358
|
-
await updateClaudeMcpServer(
|
|
359
|
-
getCompanionClaudeMcpConfigPath(companionPath),
|
|
360
|
-
descriptor.name,
|
|
361
|
-
input.enabled ? toClaudeMcpEntry(descriptor) : null,
|
|
362
|
-
);
|
|
363
|
-
}
|
|
361
|
+
await reconcileClaudeMcpContributions(ctx, inputs);
|
|
364
362
|
|
|
363
|
+
for (const input of inputs) {
|
|
365
364
|
// Guidance sections are managed blocks in CLAUDE.md. Current sections are
|
|
366
365
|
// upserted, then stale keys (content changes, disabled capability) are
|
|
367
366
|
// swept. CLAUDE.md is Claude-exclusive, so no shared-file guard applies.
|
|
@@ -389,6 +388,22 @@ export async function reconcileClaudeContributions(
|
|
|
389
388
|
}
|
|
390
389
|
}
|
|
391
390
|
|
|
391
|
+
/** Reconcile only MCP entries without touching Claude settings or guidance. */
|
|
392
|
+
async function reconcileClaudeMcpContributions(
|
|
393
|
+
ctx: SetupContext,
|
|
394
|
+
inputs: CapabilityContributionInput[],
|
|
395
|
+
): Promise<void> {
|
|
396
|
+
for (const input of inputs) {
|
|
397
|
+
for (const descriptor of input.contributions.mcpServers ?? []) {
|
|
398
|
+
await updateClaudeMcpServer(
|
|
399
|
+
getCompanionClaudeMcpConfigPath(ctx.companionPath),
|
|
400
|
+
descriptor.name,
|
|
401
|
+
input.enabled ? toClaudeMcpEntry(descriptor) : null,
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
392
407
|
// Maintain the companion `.mcp.json` shell. Managed MCP servers are reconciled
|
|
393
408
|
// from declared Capability contributions (and legacy `ctx.mcp` hosting); this
|
|
394
409
|
// only guarantees the file exists with an `mcpServers` map. Loaded at launch
|
|
@@ -688,6 +703,10 @@ export function createClaudePlugin(): ProviderPlugin {
|
|
|
688
703
|
},
|
|
689
704
|
},
|
|
690
705
|
async apply(ctx) {
|
|
706
|
+
if (ctx.scope === "hub") {
|
|
707
|
+
await syncCompanionClaudeSettings(ctx.companionPath, ctx.config);
|
|
708
|
+
return;
|
|
709
|
+
}
|
|
691
710
|
await configureClaude(ctx.companionPath);
|
|
692
711
|
await configureClaudeGuidance(ctx.companionPath);
|
|
693
712
|
await teardownLegacyClaudeBin(ctx.companionPath);
|
|
@@ -426,15 +426,14 @@ export async function reconcileOpenCodeContributions(
|
|
|
426
426
|
): Promise<void> {
|
|
427
427
|
const { companionPath } = ctx;
|
|
428
428
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
descriptor.name,
|
|
434
|
-
input.enabled ? toOpenCodeMcpEntry(descriptor) : null,
|
|
435
|
-
);
|
|
436
|
-
}
|
|
429
|
+
if (ctx.scope === "hub") {
|
|
430
|
+
await reconcileOpenCodeMcpContributions(ctx, inputs);
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
437
433
|
|
|
434
|
+
await reconcileOpenCodeMcpContributions(ctx, inputs);
|
|
435
|
+
|
|
436
|
+
for (const input of inputs) {
|
|
438
437
|
for (const pluginReference of input.contributions.pluginReferences ?? []) {
|
|
439
438
|
const configFiles = pluginReference.configFiles ?? OPENCODE_CONTRIBUTION_CONFIG_FILES;
|
|
440
439
|
for (const name of configFiles) {
|
|
@@ -479,6 +478,22 @@ export async function reconcileOpenCodeContributions(
|
|
|
479
478
|
}
|
|
480
479
|
}
|
|
481
480
|
|
|
481
|
+
/** Reconcile only MCP entries without touching OpenCode plugins or guidance. */
|
|
482
|
+
async function reconcileOpenCodeMcpContributions(
|
|
483
|
+
ctx: SetupContext,
|
|
484
|
+
inputs: CapabilityContributionInput[],
|
|
485
|
+
): Promise<void> {
|
|
486
|
+
for (const input of inputs) {
|
|
487
|
+
for (const descriptor of input.contributions.mcpServers ?? []) {
|
|
488
|
+
await updateOpenCodeMcpServer(
|
|
489
|
+
getCompanionOpenCodeConfigPath(ctx.companionPath),
|
|
490
|
+
descriptor.name,
|
|
491
|
+
input.enabled ? toOpenCodeMcpEntry(descriptor) : null,
|
|
492
|
+
);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
482
497
|
export function createOpenCodePlugin(): ProviderPlugin {
|
|
483
498
|
return {
|
|
484
499
|
id: "opencode",
|
|
@@ -509,6 +524,7 @@ export function createOpenCodePlugin(): ProviderPlugin {
|
|
|
509
524
|
},
|
|
510
525
|
},
|
|
511
526
|
async apply(ctx: SetupContext) {
|
|
527
|
+
if (ctx.scope === "hub") return;
|
|
512
528
|
await syncOpenCodeRuntimeFiles(
|
|
513
529
|
path.join(getSetupProvidersRoot(), "opencode"),
|
|
514
530
|
ctx.companionPath,
|
package/src/tools/setup.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
// oxlint-disable no-await-in-loop
|
|
2
|
-
import fs from "node:fs/promises";
|
|
3
2
|
import path from "node:path";
|
|
4
3
|
|
|
5
4
|
import { FRAMEWORK_NAME } from "../framework";
|
|
@@ -25,7 +24,7 @@ import {
|
|
|
25
24
|
collectManagedGitignoreEntries,
|
|
26
25
|
writeManagedGitignoreBlock,
|
|
27
26
|
} from "./setup/plugins/gitignore";
|
|
28
|
-
import type { PluginRegistration, SetupContext } from "./setup/plugin";
|
|
27
|
+
import type { PluginRegistration, SetupContext, SetupScope } from "./setup/plugin";
|
|
29
28
|
import { getActiveDistribution } from "../distribution";
|
|
30
29
|
import { createUvPlugin } from "./setup/package-managers/uv";
|
|
31
30
|
import type { PackageManagerSetupDeps } from "./setup/package-managers/uv";
|
|
@@ -60,10 +59,11 @@ export async function applySetupCompatibilities(
|
|
|
60
59
|
mode: "setup" | "sync",
|
|
61
60
|
plugins: PluginRegistration[] = getActiveDistribution().registry.getEntries(),
|
|
62
61
|
repoPath?: string,
|
|
62
|
+
scope: SetupScope = config.type === "hub" ? "hub" : "companion",
|
|
63
63
|
): Promise<SetupInstallationOutcome> {
|
|
64
64
|
const plan = buildSetupInstallationPlan(config, plugins);
|
|
65
65
|
const activeProviders = plan.activeProviders;
|
|
66
|
-
const ctx: SetupContext = { companionPath, config, mode, activeProviders, repoPath };
|
|
66
|
+
const ctx: SetupContext = { companionPath, config, mode, activeProviders, repoPath, scope };
|
|
67
67
|
return executeSetupInstallationPlan(ctx, plugins, plan);
|
|
68
68
|
}
|
|
69
69
|
|
|
@@ -91,48 +91,6 @@ export async function syncCompanionFiles(
|
|
|
91
91
|
);
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
export function mateFolderReadme(): string {
|
|
95
|
-
const n = FRAMEWORK_NAME;
|
|
96
|
-
const packageName =
|
|
97
|
-
getActiveDistribution().config.update?.packageName ?? `@uniqbit/${FRAMEWORK_NAME}`;
|
|
98
|
-
return [
|
|
99
|
-
`# .${FRAMEWORK_NAME}`,
|
|
100
|
-
``,
|
|
101
|
-
`This directory is managed by the **${FRAMEWORK_NAME}** companion framework (\`${packageName}\`).`,
|
|
102
|
-
``,
|
|
103
|
-
`The ${FRAMEWORK_NAME} framework keeps your AI agent's companion artifacts separate from the code it works on.`,
|
|
104
|
-
`Specs, notes, and agent config live here; code stays in the linked working repository.`,
|
|
105
|
-
``,
|
|
106
|
-
`## Common commands`,
|
|
107
|
-
``,
|
|
108
|
-
`| Command | Description |`,
|
|
109
|
-
`|---|---|`,
|
|
110
|
-
`| \`${n} companion setup\` | Initialize or re-configure this companion |`,
|
|
111
|
-
`| \`${n} companion link\` | Link a working repository to a companion |`,
|
|
112
|
-
`| \`${n} companion list\` | List linked repositories for the active working repo context |`,
|
|
113
|
-
`| \`${n} companion open\` | Inject the resolved companion into the current editor window |`,
|
|
114
|
-
`| \`${n} claude\` / \`${n} opencode\` | Launch an allowed agent from a linked working repository |`,
|
|
115
|
-
`| \`${n} doctor\` | Check current link state, installed tools, and active capabilities |`,
|
|
116
|
-
``,
|
|
117
|
-
`Run \`${n} claude\` or \`${n} opencode\` from any linked working repository directory.`,
|
|
118
|
-
``,
|
|
119
|
-
`## Configuration`,
|
|
120
|
-
``,
|
|
121
|
-
`Edit \`.${FRAMEWORK_NAME}/config/framework.yaml\` to configure:`,
|
|
122
|
-
``,
|
|
123
|
-
`- **allowedAgents** — agents permitted to launch from linked repositories`,
|
|
124
|
-
`- **capabilities** — skill and CLI tool capabilities (e.g. react-doctor, openspec, tokensave, headroom, rtk)`,
|
|
125
|
-
`- **git** — set to \`auto\` to synchronize the companion before agent launches`,
|
|
126
|
-
``,
|
|
127
|
-
].join("\n");
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
async function writeMateReadme(companionPath: string): Promise<void> {
|
|
131
|
-
const readmePath = path.join(companionPath, `.${FRAMEWORK_NAME}`, "README.md");
|
|
132
|
-
await fs.mkdir(path.dirname(readmePath), { recursive: true });
|
|
133
|
-
await fs.writeFile(readmePath, mateFolderReadme(), "utf8");
|
|
134
|
-
}
|
|
135
|
-
|
|
136
94
|
export const setupToolDeps = {
|
|
137
95
|
executeSetup: (input: SetupInput) => executeSetup(input),
|
|
138
96
|
};
|
|
@@ -160,14 +118,6 @@ export async function executeSetup(
|
|
|
160
118
|
deps.configStore ??
|
|
161
119
|
new ConfigStore(path.join(cwd, `.${FRAMEWORK_NAME}`, "config", "framework.yaml"));
|
|
162
120
|
const config = mergeWithDefaults(await configStore.load());
|
|
163
|
-
// Hubs are never companions: no setup entry path (CLI, wizard, or the
|
|
164
|
-
// setup framework tool) may write agent guidance into a hub root.
|
|
165
|
-
if (config.type === "hub") {
|
|
166
|
-
throw new ConfigError(
|
|
167
|
-
`A companion hub cannot be set up as a companion: ${cwd}. Use \`${FRAMEWORK_NAME} hub\` commands to manage the hub.`,
|
|
168
|
-
);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
121
|
if (input.allowedAgents !== undefined) {
|
|
172
122
|
config.allowedAgents = [...new Set(input.allowedAgents)];
|
|
173
123
|
}
|
|
@@ -202,12 +152,13 @@ export async function executeSetup(
|
|
|
202
152
|
await hydrateDynamicPlugins({ companionPath });
|
|
203
153
|
}
|
|
204
154
|
await applySetupCompatibilities(companionPath, config, "setup");
|
|
205
|
-
await invalidateInstallState({
|
|
155
|
+
await invalidateInstallState({
|
|
156
|
+
kind: config.type === "hub" ? "hub" : "companion",
|
|
157
|
+
companionPath,
|
|
158
|
+
});
|
|
206
159
|
|
|
207
160
|
await globalConfigStore.register(companionPath);
|
|
208
161
|
|
|
209
|
-
await writeMateReadme(companionPath);
|
|
210
|
-
|
|
211
162
|
// Setup no longer fans out to linked repos: capabilities that touch a working repo
|
|
212
163
|
// (companion files on launch, the tokensave/graphify graph via `mate cap index`)
|
|
213
164
|
// are applied in that repo's own context, not eagerly from here.
|