@north-light/crouter 0.3.230 → 0.3.232
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/dist/api/client.d.ts +3 -1
- package/dist/api/client.js +4 -0
- package/dist/api/dto/canvas.d.ts +10 -0
- package/dist/api/dto/common.d.ts +1 -1
- package/dist/api/dto/health.d.ts +2 -1
- package/dist/api/dto/lifecycle.d.ts +3 -4
- package/dist/api/dto/messages.d.ts +5 -4
- package/dist/api/dto/nodes.d.ts +2 -0
- package/dist/api/dto/profiles.d.ts +5 -0
- package/dist/api/routes.d.ts +1 -0
- package/dist/api/routes.js +1 -0
- package/dist/builtin-memory/00-runtime-base/00-authoring.md +8 -0
- package/dist/builtin-memory/00-runtime-base/01-escalation.md +1 -1
- package/dist/builtin-memory/01-spine/00-has-manager.md +1 -1
- package/dist/builtin-memory/02-turn-lifecycle/00-ending-a-turn.md +5 -0
- package/dist/builtin-memory/02-turn-lifecycle/02-resident.md +5 -3
- package/dist/builtin-memory/04-orchestration-kernel.md +2 -2
- package/dist/builtin-memory/insights/capture.md +3 -2
- package/dist/builtin-pi-packages/pi-crtr-extensions/README.md +6 -1
- package/dist/clients/attach/render/diagram.js +13 -5
- package/dist/clients/attach/render/page-block.d.ts +0 -1
- package/dist/clients/attach/render/page-block.js +4 -57
- package/dist/clients/attach/viewer.js +570 -563
- package/dist/clients/inbox/__tests__/integration/inbox-controller.test.js +9 -0
- package/dist/clients/inbox/__tests__/integration/mount-panel.test.js +62 -1
- package/dist/clients/inbox/controller.d.ts +10 -0
- package/dist/clients/inbox/controller.js +56 -12
- package/dist/clients/inbox/tui/input.js +38 -10
- package/dist/clients/inbox/tui/page-body.d.ts +10 -0
- package/dist/clients/inbox/tui/page-body.js +66 -0
- package/dist/clients/inbox/tui/panel.js +6 -4
- package/dist/clients/inbox/tui/render.js +89 -17
- package/dist/clients/inbox/tui/types.d.ts +4 -4
- package/dist/commands/__tests__/human.test.js +18 -3
- package/dist/commands/__tests__/node-message.test.js +3 -3
- package/dist/commands/api-client.js +1 -7
- package/dist/commands/canvas-config.js +6 -14
- package/dist/commands/canvas-use.js +4 -6
- package/dist/commands/cron.js +16 -22
- package/dist/commands/human/prompts.d.ts +1 -1
- package/dist/commands/human/prompts.js +118 -112
- package/dist/commands/human/request.js +13 -14
- package/dist/commands/human/review.js +3 -4
- package/dist/commands/human/shared.d.ts +6 -0
- package/dist/commands/human/shared.js +43 -5
- package/dist/commands/human.js +1 -1
- package/dist/commands/memory/delete.js +4 -6
- package/dist/commands/memory/edit.js +0 -4
- package/dist/commands/memory/move.js +3 -5
- package/dist/commands/memory/shared.d.ts +1 -1
- package/dist/commands/memory/shared.js +9 -5
- package/dist/commands/memory/write.js +60 -29
- package/dist/commands/memory.js +1 -1
- package/dist/commands/node/bash.js +6 -9
- package/dist/commands/node/create.js +89 -22
- package/dist/commands/node/inspect.js +3 -3
- package/dist/commands/node/lifecycle.js +30 -27
- package/dist/commands/node/message.js +24 -45
- package/dist/commands/node/subscription.js +6 -15
- package/dist/commands/node/wait.js +2 -3
- package/dist/commands/node-lifecycle-revive.js +1 -12
- package/dist/commands/pkg/browse/actions.js +2 -3
- package/dist/commands/pkg/market-manage.js +2 -5
- package/dist/commands/pkg/plugin-manage.js +7 -8
- package/dist/commands/profile/default.js +5 -5
- package/dist/commands/profile/delete.js +1 -1
- package/dist/commands/profile/env.js +9 -15
- package/dist/commands/profile/kind.js +3 -7
- package/dist/commands/profile/meta.js +3 -5
- package/dist/commands/profile/new.js +0 -6
- package/dist/commands/profile/pause.js +4 -8
- package/dist/commands/profile/project.js +5 -9
- package/dist/commands/profile/rename.js +3 -7
- package/dist/commands/profile/show.js +3 -3
- package/dist/commands/profile.js +4 -3
- package/dist/commands/surface-tmux-spread.js +1 -3
- package/dist/commands/sys/config.js +3 -4
- package/dist/commands/sys/support/prepare.js +8 -4
- package/dist/commands/sys/support/submit.js +2 -3
- package/dist/commands/sys/sync-deps.js +1 -9
- package/dist/commands/sys/sync-project-guidance.js +1 -7
- package/dist/commands/sys/sync-skills.js +1 -11
- package/dist/core/__tests__/cron-node-sink-parked-root.test.d.ts +1 -0
- package/dist/core/__tests__/cron-node-sink-parked-root.test.js +147 -0
- package/dist/core/__tests__/history-inbox.test.js +11 -1
- package/dist/core/__tests__/human-deliver.test.js +2 -1
- package/dist/core/__tests__/integration/command-plugins.test.js +0 -1
- package/dist/core/__tests__/integration/deferred-no-wake.test.js +0 -1
- package/dist/core/__tests__/lifecycle.test.js +30 -2
- package/dist/core/__tests__/revive-parked-fresh.test.d.ts +1 -0
- package/dist/core/__tests__/revive-parked-fresh.test.js +109 -0
- package/dist/core/__tests__/seam/dormancy-release.test.js +32 -5
- package/dist/core/canvas/attention.d.ts +2 -0
- package/dist/core/canvas/attention.js +25 -18
- package/dist/core/canvas/extensions.d.ts +1 -1
- package/dist/core/canvas/extensions.js +7 -1
- package/dist/core/canvas/history.js +20 -2
- package/dist/core/canvas/types.d.ts +1 -1
- package/dist/core/command.js +33 -8
- package/dist/core/help.d.ts +28 -2
- package/dist/core/help.js +46 -10
- package/dist/core/human/__tests__/page-html-markdown.test.d.ts +1 -0
- package/dist/core/human/__tests__/page-html-markdown.test.js +48 -0
- package/dist/core/human/component-docs.js +4 -4
- package/dist/core/human/page-html-markdown.d.ts +8 -0
- package/dist/core/human/page-html-markdown.js +260 -0
- package/dist/core/memory/lint.d.ts +15 -0
- package/dist/core/memory/lint.js +150 -90
- package/dist/core/profiles/__tests__/fuzzy-match.test.d.ts +1 -0
- package/dist/core/profiles/__tests__/fuzzy-match.test.js +51 -0
- package/dist/core/profiles/fuzzy-match.d.ts +19 -0
- package/dist/core/profiles/fuzzy-match.js +92 -0
- package/dist/core/profiles/manifest.d.ts +14 -7
- package/dist/core/profiles/manifest.js +62 -12
- package/dist/core/profiles/select.d.ts +3 -1
- package/dist/core/profiles/select.js +5 -3
- package/dist/core/profiles/state-block.js +4 -3
- package/dist/core/runtime/boot-root.d.ts +3 -2
- package/dist/core/runtime/canvas-extensions.d.ts +7 -1
- package/dist/core/runtime/canvas-extensions.js +8 -1
- package/dist/core/runtime/lifecycle.d.ts +11 -2
- package/dist/core/runtime/lifecycle.js +15 -2
- package/dist/core/runtime/model-selection.d.ts +4 -0
- package/dist/core/runtime/model-selection.js +5 -0
- package/dist/core/runtime/nodes.js +5 -0
- package/dist/core/runtime/reopen.d.ts +6 -0
- package/dist/core/runtime/reopen.js +12 -1
- package/dist/core/runtime/revive.d.ts +6 -0
- package/dist/core/runtime/revive.js +22 -2
- package/dist/core/runtime/spawn.d.ts +5 -2
- package/dist/core/runtime/spawn.js +18 -32
- package/dist/core/runtime/structured-output.d.ts +6 -0
- package/dist/core/runtime/structured-output.js +6 -0
- package/dist/core/substrate/__tests__/surface-match-command.test.d.ts +1 -0
- package/dist/core/substrate/__tests__/surface-match-command.test.js +89 -0
- package/dist/core/substrate/on-read.js +2 -1
- package/dist/core/substrate/surface-match.js +164 -12
- package/dist/core/termrender/version.d.ts +1 -1
- package/dist/core/termrender/version.js +1 -1
- package/dist/core/user-settings.js +1 -1
- package/dist/daemon/api/__tests__/broker-settle-park.test.d.ts +1 -0
- package/dist/daemon/api/__tests__/broker-settle-park.test.js +102 -0
- package/dist/daemon/api/__tests__/canvas-snapshot-fields.test.d.ts +1 -0
- package/dist/daemon/api/__tests__/canvas-snapshot-fields.test.js +188 -0
- package/dist/daemon/api/__tests__/node-create-description.test.d.ts +1 -0
- package/dist/daemon/api/__tests__/node-create-description.test.js +83 -0
- package/dist/daemon/api/__tests__/profile-metadata-route.test.d.ts +1 -0
- package/dist/daemon/api/__tests__/profile-metadata-route.test.js +92 -0
- package/dist/daemon/api/__tests__/reopen-delivery.test.d.ts +1 -0
- package/dist/daemon/api/__tests__/reopen-delivery.test.js +173 -0
- package/dist/daemon/api/handlers/broker-ops.js +21 -0
- package/dist/daemon/api/handlers/canvas.js +10 -0
- package/dist/daemon/api/handlers/messages.js +25 -16
- package/dist/daemon/api/handlers/nodes.js +5 -0
- package/dist/daemon/api/handlers/profiles.js +22 -1
- package/dist/daemon/cron-run.js +19 -1
- package/dist/daemon/manage.d.ts +16 -1
- package/dist/daemon/manage.js +20 -1
- package/dist/daemon/park-pending.d.ts +13 -0
- package/dist/daemon/park-pending.js +42 -0
- package/dist/daemon/reconcilers/broker-supervision.d.ts +13 -0
- package/dist/daemon/reconcilers/broker-supervision.js +139 -21
- package/dist/daemon/reconcilers/live-obligation.d.ts +10 -4
- package/dist/daemon/reconcilers/live-obligation.js +7 -3
- package/dist/daemon/reconcilers/storage-maintenance.d.ts +0 -4
- package/dist/daemon/reconcilers/storage-maintenance.js +1 -33
- package/dist/pi-extensions/canvas-prompt-scrub.d.ts +13 -0
- package/dist/pi-extensions/canvas-prompt-scrub.js +53 -0
- package/dist/shared/generated-context.d.ts +7 -0
- package/dist/shared/generated-context.js +11 -0
- package/package.json +4 -4
- package/runtime.lock.json +2 -2
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/strip-skills-docs.ts +0 -47
|
@@ -124,7 +124,6 @@ const nodeWait = defineLeaf({
|
|
|
124
124
|
],
|
|
125
125
|
output: [
|
|
126
126
|
{ name: 'node_id', type: 'string', required: true, constraint: 'The terminal node that declared the wait.' },
|
|
127
|
-
{ name: 'controller', type: 'string', required: true, constraint: 'The named live sender whose next inbox delivery clears this wait.' },
|
|
128
127
|
],
|
|
129
128
|
outputKind: 'object',
|
|
130
129
|
effects: ['Durably records the controller on this node. The stop guard permits dormancy only while that controller remains active or idle; its next inbox delivery clears the record before the delivery wakes this node.'],
|
|
@@ -146,9 +145,9 @@ const nodeWait = defineLeaf({
|
|
|
146
145
|
await cliClient()
|
|
147
146
|
.waitNode(nodeId, { controller })
|
|
148
147
|
.catch((err) => rethrowAsCliError(err));
|
|
149
|
-
return { node_id: nodeId
|
|
148
|
+
return { node_id: nodeId };
|
|
150
149
|
},
|
|
151
|
-
render: (
|
|
150
|
+
render: () => 'Waiting for the controller. End your turn to dorm; its next message wakes you and clears this wait.',
|
|
152
151
|
});
|
|
153
152
|
export const nodeWaitBranch = defineBranch({
|
|
154
153
|
name: 'wait',
|
|
@@ -101,11 +101,10 @@ export const nodeReviveLeaf = defineLeaf({
|
|
|
101
101
|
},
|
|
102
102
|
],
|
|
103
103
|
output: [
|
|
104
|
-
{ name: 'window', type: 'string', required: false, constraint: 'Always null — the revived broker is headless and opens no tmux window. Kept for caller back-compat.' },
|
|
105
|
-
{ name: 'session', type: 'string', required: false, constraint: 'The node\'s last live location session, or null — the headless broker has no tmux session of its own.' },
|
|
106
104
|
{ name: 'resumed', type: 'boolean', required: false, constraint: 'True ONLY for a true resume (the existing `.jsonl` replayed as-is). False for a --fresh revive, whether that landed as an in-place CYCLE (an existing `.jsonl` reused with a fresh `crtr-cycle` branch — pi is still told --session, but this is not a resume) or a genuinely fresh launch (no `.jsonl` existed). Absent for a --now kick.' },
|
|
107
105
|
{ name: 'ready', type: 'boolean', required: false, constraint: 'True when the revived broker\'s view.sock accepted a connection before return — the node is immediately attachable/drivable. Absent for a --now kick.' },
|
|
108
106
|
{ name: 'kicked', type: 'boolean', required: false, constraint: 'True when --now SIGTERM\'d the hanging node\'s live broker (the daemon resumes it on the saved session within ~20s). Absent for an ordinary revive.' },
|
|
107
|
+
{ name: 'message', type: 'string', required: false, constraint: 'Kick confirmation naming the signalled node, pid, and the daemon\'s ~20s resume handoff. Present only for --now.' },
|
|
109
108
|
],
|
|
110
109
|
outputKind: 'object',
|
|
111
110
|
effects: [
|
|
@@ -192,10 +191,6 @@ export const nodeReviveLeaf = defineLeaf({
|
|
|
192
191
|
/* best-effort: the broker may have just died; the daemon owns the resume */
|
|
193
192
|
}
|
|
194
193
|
return {
|
|
195
|
-
window: null,
|
|
196
|
-
// The DTO carries no `tmux_session` (the headless broker has none); the
|
|
197
|
-
// pre-API leaf returned `meta.tmux_session ?? null`, which is null here.
|
|
198
|
-
session: null,
|
|
199
194
|
kicked: true,
|
|
200
195
|
message: `Sent SIGTERM to ${fullName(detail)} (${nodeId}, pid ${pid}). The daemon will resume it on the saved session within ~20s (crash→grace→resume).`,
|
|
201
196
|
};
|
|
@@ -227,12 +222,6 @@ export const nodeReviveLeaf = defineLeaf({
|
|
|
227
222
|
// return need this leaf to wait until the socket accepts.
|
|
228
223
|
const ready = await waitForViewSocketReady(nodeId);
|
|
229
224
|
return {
|
|
230
|
-
// Always null (broker headless, no tmux window); `undefined` omits it from
|
|
231
|
-
// the JSON payload, matching the pre-API leaf's `result.window ?? undefined`.
|
|
232
|
-
window: undefined,
|
|
233
|
-
// The revive DTO carries no location session (the headless broker has none);
|
|
234
|
-
// the pre-API leaf returned `result.session`, which was null here.
|
|
235
|
-
session: null,
|
|
236
225
|
resumed: result.resumed,
|
|
237
226
|
ready,
|
|
238
227
|
};
|
|
@@ -186,9 +186,8 @@ export async function runAction(request) {
|
|
|
186
186
|
return missing("Choose a marketplace to remove.");
|
|
187
187
|
if (request.scope === undefined)
|
|
188
188
|
return missing("Choose a marketplace scope to remove.");
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
return { ok: true, message: `Removed marketplace ${name}.` };
|
|
189
|
+
await marketRemove.run({ name: request.marketplace, scope: request.scope });
|
|
190
|
+
return { ok: true, message: `Removed marketplace ${request.marketplace}.` };
|
|
192
191
|
}
|
|
193
192
|
}
|
|
194
193
|
return missing("Unsupported action.");
|
|
@@ -86,10 +86,7 @@ export const marketRemove = defineLeaf({
|
|
|
86
86
|
{ kind: 'positional', name: 'name', type: 'string', required: true, constraint: 'Marketplace name to remove.' },
|
|
87
87
|
{ kind: 'flag', name: 'scope', type: 'enum', choices: ['user', 'project'], required: false, constraint: 'Narrows resolution.' },
|
|
88
88
|
],
|
|
89
|
-
output: [
|
|
90
|
-
{ name: 'name', type: 'string', required: true, constraint: 'Removed marketplace name.' },
|
|
91
|
-
{ name: 'removed', type: 'boolean', required: true, constraint: 'Always true on success.' },
|
|
92
|
-
],
|
|
89
|
+
output: [],
|
|
93
90
|
outputKind: 'object',
|
|
94
91
|
effects: ['Deletes the marketplace directory. Removes the entry from config.json. Removes plugin files and config entries sourced from that marketplace in the same scope.'],
|
|
95
92
|
},
|
|
@@ -144,7 +141,7 @@ export const marketRemove = defineLeaf({
|
|
|
144
141
|
delete c.plugins[pluginName];
|
|
145
142
|
}
|
|
146
143
|
});
|
|
147
|
-
return {
|
|
144
|
+
return {};
|
|
148
145
|
},
|
|
149
146
|
});
|
|
150
147
|
/** Stage a fresh checkout beside the active root. A clone that fails throws
|
|
@@ -793,7 +793,6 @@ export const pluginRemove = defineLeaf({
|
|
|
793
793
|
{ kind: 'flag', name: 'scope', type: 'enum', choices: ['user', 'project'], required: false, constraint: 'Default: searches all scopes.' },
|
|
794
794
|
],
|
|
795
795
|
output: [
|
|
796
|
-
{ name: 'removed', type: 'boolean', required: true, constraint: 'True if removed from at least one scope.' },
|
|
797
796
|
{ name: 'scopes', type: 'string[]', required: true, constraint: 'Scopes the plugin was removed from.' },
|
|
798
797
|
],
|
|
799
798
|
outputKind: 'object',
|
|
@@ -832,7 +831,7 @@ export const pluginRemove = defineLeaf({
|
|
|
832
831
|
if (removedFrom.length === 0) {
|
|
833
832
|
throw notFound(`plugin not found: ${name}`);
|
|
834
833
|
}
|
|
835
|
-
return {
|
|
834
|
+
return { scopes: removedFrom };
|
|
836
835
|
},
|
|
837
836
|
});
|
|
838
837
|
export const pluginEnable = defineLeaf({
|
|
@@ -847,9 +846,7 @@ export const pluginEnable = defineLeaf({
|
|
|
847
846
|
{ kind: 'flag', name: 'scope', type: 'enum', choices: ['user', 'project'], required: false, constraint: 'Default: scope where the plugin is installed.' },
|
|
848
847
|
],
|
|
849
848
|
output: [
|
|
850
|
-
{ name: 'name', type: 'string', required: true, constraint: 'Plugin name.' },
|
|
851
849
|
{ name: 'scope', type: 'string', required: true, constraint: 'Scope the change was applied in.' },
|
|
852
|
-
{ name: 'enabled', type: 'boolean', required: true, constraint: 'Always true.' },
|
|
853
850
|
{ name: 'memory', type: 'object', required: false, constraint: 'Present only when the plugin ships a memory store. {docs: integer (documents checked), migrated: string[] (store-relative documents rewritten to reach exact canonical identity), linkedSource?: string (the caller-owned directory converged in place, present only for a symlinked install)}.' },
|
|
854
851
|
],
|
|
855
852
|
outputKind: 'object',
|
|
@@ -868,7 +865,8 @@ export const pluginEnable = defineLeaf({
|
|
|
868
865
|
throw notFound(`plugin manifest not found at ${target.root}/.crouter-plugin/plugin.json`);
|
|
869
866
|
const scopeRootPath = target.scope === 'project' ? requireScopeRoot('project') : userScopeRoot();
|
|
870
867
|
const memory = await assertPluginCandidateValid(manifest, target.root, target.scope, scopeRootPath, `${target.root}/.crouter-plugin/plugin.json`, undefined, isSymlink(target.root) ? 'linked' : 'package');
|
|
871
|
-
|
|
868
|
+
const result = await setPluginEnabled(input, true);
|
|
869
|
+
return { scope: result['scope'], ...(memory !== undefined ? { memory } : {}) };
|
|
872
870
|
},
|
|
873
871
|
});
|
|
874
872
|
export const pluginDisable = defineLeaf({
|
|
@@ -883,14 +881,15 @@ export const pluginDisable = defineLeaf({
|
|
|
883
881
|
{ kind: 'flag', name: 'scope', type: 'enum', choices: ['user', 'project'], required: false, constraint: 'Default: scope where the plugin is installed.' },
|
|
884
882
|
],
|
|
885
883
|
output: [
|
|
886
|
-
{ name: 'name', type: 'string', required: true, constraint: 'Plugin name.' },
|
|
887
884
|
{ name: 'scope', type: 'string', required: true, constraint: 'Scope the change was applied in.' },
|
|
888
|
-
{ name: 'enabled', type: 'boolean', required: true, constraint: 'Always false.' },
|
|
889
885
|
],
|
|
890
886
|
outputKind: 'object',
|
|
891
887
|
effects: ['Sets plugin enabled=false in config.json.'],
|
|
892
888
|
},
|
|
893
|
-
run: async (input) =>
|
|
889
|
+
run: async (input) => {
|
|
890
|
+
const result = await setPluginEnabled(input, false);
|
|
891
|
+
return { scope: result['scope'] };
|
|
892
|
+
},
|
|
894
893
|
});
|
|
895
894
|
export const pluginUpdate = defineLeaf({
|
|
896
895
|
name: 'update',
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// `crtr profile default` manages the per-cwd profile-selection pin.
|
|
2
2
|
import { defineLeaf, defineBranch } from '../../core/command.js';
|
|
3
3
|
import { InputError } from '../../core/io.js';
|
|
4
|
-
import { loadProfileManifest } from '../../core/profiles/manifest.js';
|
|
4
|
+
import { loadProfileManifest, resolveProfileOperand } from '../../core/profiles/manifest.js';
|
|
5
5
|
import { profileCoversCwd } from '../../core/profiles/select.js';
|
|
6
6
|
import { getDefaultProfileId, setDefaultProfileId, clearDefaultProfile, resolveBindingCwd, } from '../../core/profiles/default-binding.js';
|
|
7
7
|
const setLeaf = defineLeaf({
|
|
@@ -16,14 +16,14 @@ const setLeaf = defineLeaf({
|
|
|
16
16
|
kind: 'positional',
|
|
17
17
|
name: 'profile',
|
|
18
18
|
required: true,
|
|
19
|
-
constraint: '
|
|
19
|
+
constraint: 'Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr. Must already cover the current directory (be at/above/below it in its project purview); this pin does not change automatic memory disclosure.',
|
|
20
20
|
},
|
|
21
21
|
],
|
|
22
22
|
output: [
|
|
23
23
|
{ name: 'dir', type: 'string', required: true, constraint: "The resolved directory the pin was set for." },
|
|
24
24
|
{ name: 'profile_id', type: 'string', required: true, constraint: 'The pinned profile id.' },
|
|
25
25
|
{ name: 'name', type: 'string', required: true, constraint: 'The pinned profile name.' },
|
|
26
|
-
{ name: 'follow_up', type: 'string', required: true, constraint: '
|
|
26
|
+
{ name: 'follow_up', type: 'string', required: true, constraint: 'The resulting ambient effect.' },
|
|
27
27
|
],
|
|
28
28
|
outputKind: 'object',
|
|
29
29
|
effects: ['Writes this directory\'s pin into `~/.crouter/profile-defaults.json`. The next launch here auto-picks this profile with no prompt (override once with `crtr --pick-profile`).'],
|
|
@@ -31,7 +31,7 @@ const setLeaf = defineLeaf({
|
|
|
31
31
|
run: async (_input) => {
|
|
32
32
|
const cwd = process.cwd();
|
|
33
33
|
const resolved = resolveBindingCwd(cwd);
|
|
34
|
-
const entry =
|
|
34
|
+
const entry = resolveProfileOperand(_input['profile']);
|
|
35
35
|
if (!profileCoversCwd(entry, resolved)) {
|
|
36
36
|
throw new InputError({
|
|
37
37
|
error: 'not_covered',
|
|
@@ -44,7 +44,7 @@ const setLeaf = defineLeaf({
|
|
|
44
44
|
dir: resolved,
|
|
45
45
|
profile_id: entry.profileId,
|
|
46
46
|
name: entry.manifest.name,
|
|
47
|
-
follow_up: `Launches here now auto-pick "${entry.manifest.name}"
|
|
47
|
+
follow_up: `Launches here now auto-pick "${entry.manifest.name}".`,
|
|
48
48
|
};
|
|
49
49
|
},
|
|
50
50
|
});
|
|
@@ -12,7 +12,7 @@ export const deleteLeaf = defineLeaf({
|
|
|
12
12
|
kind: 'positional',
|
|
13
13
|
name: 'profile',
|
|
14
14
|
required: true,
|
|
15
|
-
constraint: 'Exact profile id, or a unique manifest name.',
|
|
15
|
+
constraint: 'Exact profile id, or a unique manifest name. Deletion never guesses at a near miss — unlike every other profile verb, an unrecognized value fails.',
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
18
|
kind: 'flag',
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// `core/profiles/env-store.ts` for the on-disk (0600) store this wraps.
|
|
9
9
|
import { defineLeaf, defineBranch } from '../../core/command.js';
|
|
10
10
|
import { InputError } from '../../core/io.js';
|
|
11
|
-
import {
|
|
11
|
+
import { resolveProfileOperand } from '../../core/profiles/manifest.js';
|
|
12
12
|
import { validateEnvVarName } from '../../core/env-name.js';
|
|
13
13
|
import { listProfileEnvNames, setProfileEnvVar, removeProfileEnvVar } from '../../core/profiles/env-store.js';
|
|
14
14
|
/** Strips exactly one trailing line ending (`\r\n` or `\n`) — the one
|
|
@@ -47,7 +47,7 @@ const setLeaf = defineLeaf({
|
|
|
47
47
|
kind: 'positional',
|
|
48
48
|
name: 'profile',
|
|
49
49
|
required: true,
|
|
50
|
-
constraint: '
|
|
50
|
+
constraint: 'Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr.',
|
|
51
51
|
},
|
|
52
52
|
{
|
|
53
53
|
kind: 'flag',
|
|
@@ -65,9 +65,8 @@ const setLeaf = defineLeaf({
|
|
|
65
65
|
],
|
|
66
66
|
output: [
|
|
67
67
|
{ name: 'profile_id', type: 'string', required: true, constraint: 'Stable directory id.' },
|
|
68
|
-
{ name: 'name', type: 'string', required: true, constraint: 'The env var name written.' },
|
|
69
68
|
{ name: 'created', type: 'boolean', required: true, constraint: 'true when this name was newly added, false when it replaced an existing value.' },
|
|
70
|
-
{ name: 'follow_up', type: 'string', required: true, constraint: '
|
|
69
|
+
{ name: 'follow_up', type: 'string', required: true, constraint: 'The effect on already-running nodes.' },
|
|
71
70
|
],
|
|
72
71
|
outputKind: 'object',
|
|
73
72
|
effects: [
|
|
@@ -78,7 +77,7 @@ const setLeaf = defineLeaf({
|
|
|
78
77
|
run: async (input) => {
|
|
79
78
|
const name = input['name'];
|
|
80
79
|
requireValidName(name);
|
|
81
|
-
const { profileId } =
|
|
80
|
+
const { profileId } = resolveProfileOperand(input['profile']);
|
|
82
81
|
const value = stripSingleTrailingLineEnding(input['value'] ?? '');
|
|
83
82
|
if (value === '') {
|
|
84
83
|
throw new InputError({
|
|
@@ -91,9 +90,8 @@ const setLeaf = defineLeaf({
|
|
|
91
90
|
const created = setProfileEnvVar(profileId, name, value);
|
|
92
91
|
return {
|
|
93
92
|
profile_id: profileId,
|
|
94
|
-
name,
|
|
95
93
|
created,
|
|
96
|
-
follow_up:
|
|
94
|
+
follow_up: 'A running node under this profile picks up the change on its next revive.',
|
|
97
95
|
};
|
|
98
96
|
},
|
|
99
97
|
});
|
|
@@ -109,7 +107,7 @@ const listLeaf = defineLeaf({
|
|
|
109
107
|
kind: 'positional',
|
|
110
108
|
name: 'profile',
|
|
111
109
|
required: true,
|
|
112
|
-
constraint: '
|
|
110
|
+
constraint: 'Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr.',
|
|
113
111
|
},
|
|
114
112
|
],
|
|
115
113
|
output: [
|
|
@@ -122,7 +120,7 @@ const listLeaf = defineLeaf({
|
|
|
122
120
|
effects: ['None. Read-only \u2014 and value-blind by construction: this leaf never reads the stored values.'],
|
|
123
121
|
},
|
|
124
122
|
run: async (input) => {
|
|
125
|
-
const { profileId } =
|
|
123
|
+
const { profileId } = resolveProfileOperand(input['profile']);
|
|
126
124
|
const names = listProfileEnvNames(profileId);
|
|
127
125
|
return {
|
|
128
126
|
profile_id: profileId,
|
|
@@ -146,7 +144,7 @@ const removeLeaf = defineLeaf({
|
|
|
146
144
|
kind: 'positional',
|
|
147
145
|
name: 'profile',
|
|
148
146
|
required: true,
|
|
149
|
-
constraint: '
|
|
147
|
+
constraint: 'Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr.',
|
|
150
148
|
},
|
|
151
149
|
{
|
|
152
150
|
kind: 'flag',
|
|
@@ -158,9 +156,7 @@ const removeLeaf = defineLeaf({
|
|
|
158
156
|
],
|
|
159
157
|
output: [
|
|
160
158
|
{ name: 'profile_id', type: 'string', required: true, constraint: 'Stable directory id.' },
|
|
161
|
-
{ name: 'name', type: 'string', required: true, constraint: 'The env var name targeted.' },
|
|
162
159
|
{ name: 'removed', type: 'boolean', required: true, constraint: 'true when a value existed and was removed; false when nothing was stored under this name.' },
|
|
163
|
-
{ name: 'follow_up', type: 'string', required: true, constraint: 'Concrete next commands.' },
|
|
164
160
|
],
|
|
165
161
|
outputKind: 'object',
|
|
166
162
|
effects: [
|
|
@@ -169,15 +165,13 @@ const removeLeaf = defineLeaf({
|
|
|
169
165
|
],
|
|
170
166
|
},
|
|
171
167
|
run: async (input) => {
|
|
172
|
-
const { profileId } =
|
|
168
|
+
const { profileId } = resolveProfileOperand(input['profile']);
|
|
173
169
|
const name = input['name'];
|
|
174
170
|
requireValidName(name);
|
|
175
171
|
const removed = removeProfileEnvVar(profileId, name);
|
|
176
172
|
return {
|
|
177
173
|
profile_id: profileId,
|
|
178
|
-
name,
|
|
179
174
|
removed,
|
|
180
|
-
follow_up: `List remaining names with \`crtr profile env list ${profileId}\`.`,
|
|
181
175
|
};
|
|
182
176
|
},
|
|
183
177
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineLeaf } from '../../core/command.js';
|
|
2
2
|
import { assertInstalledKind, readMergedLaunchConfig } from '../../core/config.js';
|
|
3
|
-
import {
|
|
3
|
+
import { resolveProfileOperand, setProfileDefaultKind } from '../../core/profiles/manifest.js';
|
|
4
4
|
import { stateBlock } from '../../core/help.js';
|
|
5
5
|
function kindsStateBlock() {
|
|
6
6
|
return stateBlock('kinds', { count: Object.keys(readMergedLaunchConfig().kinds).length }, Object.keys(readMergedLaunchConfig().kinds).sort().join('\n'));
|
|
@@ -13,13 +13,11 @@ export const kindLeaf = defineLeaf({
|
|
|
13
13
|
name: 'profile kind',
|
|
14
14
|
summary: "set a profile's manifest `default_kind` for creates that omit --kind",
|
|
15
15
|
params: [
|
|
16
|
-
{ kind: 'positional', name: 'profile', required: true, constraint: '
|
|
16
|
+
{ kind: 'positional', name: 'profile', required: true, constraint: 'Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr.' },
|
|
17
17
|
{ kind: 'positional', name: 'kind', required: true, constraint: 'Installed persona kind to use by default. The live <kinds> list below is the accepted value set.' },
|
|
18
18
|
],
|
|
19
19
|
output: [
|
|
20
20
|
{ name: 'profile_id', type: 'string', required: true, constraint: 'Stable directory id.' },
|
|
21
|
-
{ name: 'default_kind', type: 'string', required: true, constraint: 'The installed kind stored for creates that omit --kind.' },
|
|
22
|
-
{ name: 'follow_up', type: 'string', required: true, constraint: 'Concrete next command.' },
|
|
23
21
|
],
|
|
24
22
|
dynamicState: kindsStateBlock,
|
|
25
23
|
outputKind: 'object',
|
|
@@ -28,12 +26,10 @@ export const kindLeaf = defineLeaf({
|
|
|
28
26
|
run: async (input) => {
|
|
29
27
|
const kind = input['kind'];
|
|
30
28
|
assertInstalledKind(kind);
|
|
31
|
-
const { profileId } =
|
|
29
|
+
const { profileId } = resolveProfileOperand(input['profile']);
|
|
32
30
|
const { manifest } = setProfileDefaultKind(profileId, kind);
|
|
33
31
|
return {
|
|
34
32
|
profile_id: profileId,
|
|
35
|
-
default_kind: manifest.default_kind,
|
|
36
|
-
follow_up: `Create a node under it without --kind, or inspect it with \`crtr profile show ${profileId}\`.`,
|
|
37
33
|
};
|
|
38
34
|
},
|
|
39
35
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineLeaf } from '../../core/command.js';
|
|
2
2
|
import { InputError } from '../../core/io.js';
|
|
3
|
-
import {
|
|
3
|
+
import { resolveProfileOperand, updateProfileMetadata } from '../../core/profiles/manifest.js';
|
|
4
4
|
/** Fold `KEY=VALUE` flag repetitions into one map. Key-shape validation stays
|
|
5
5
|
* with the manifest store (`assertProfileMetadata`); this only splits. */
|
|
6
6
|
export function resolveMetaPairs(raw, field) {
|
|
@@ -33,14 +33,13 @@ export const metaLeaf = defineLeaf({
|
|
|
33
33
|
name: 'profile meta',
|
|
34
34
|
summary: "merge entries into (or drop entries from) a profile manifest's `metadata` map",
|
|
35
35
|
params: [
|
|
36
|
-
{ kind: 'positional', name: 'profile', required: true, constraint: '
|
|
36
|
+
{ kind: 'positional', name: 'profile', required: true, constraint: 'Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr.' },
|
|
37
37
|
{ kind: 'flag', name: 'set', type: 'string', required: false, repeatable: true, constraint: 'KEY=VALUE to merge over the stored map (repeat per entry). KEY starts with a letter or digit, followed by letters, digits, `_`, or `-`; an existing key is overwritten.' },
|
|
38
38
|
{ kind: 'flag', name: 'unset', type: 'string', required: false, repeatable: true, constraint: 'KEY to remove (repeat per entry). Removing an absent key is a no-op.' },
|
|
39
39
|
],
|
|
40
40
|
output: [
|
|
41
41
|
{ name: 'profile_id', type: 'string', required: true, constraint: 'Stable directory id.' },
|
|
42
42
|
{ name: 'metadata', type: 'object', required: true, constraint: 'The full resulting metadata map.' },
|
|
43
|
-
{ name: 'follow_up', type: 'string', required: true, constraint: 'Concrete next command.' },
|
|
44
43
|
],
|
|
45
44
|
outputKind: 'object',
|
|
46
45
|
effects: [
|
|
@@ -58,12 +57,11 @@ export const metaLeaf = defineLeaf({
|
|
|
58
57
|
next: 'Repeat --set/--unset per entry.',
|
|
59
58
|
});
|
|
60
59
|
}
|
|
61
|
-
const { profileId } =
|
|
60
|
+
const { profileId } = resolveProfileOperand(input['profile']);
|
|
62
61
|
const { manifest } = updateProfileMetadata(profileId, set, unset);
|
|
63
62
|
return {
|
|
64
63
|
profile_id: profileId,
|
|
65
64
|
metadata: manifest.metadata ?? {},
|
|
66
|
-
follow_up: `Inspect it with \`crtr profile show ${profileId}\`.`,
|
|
67
65
|
};
|
|
68
66
|
},
|
|
69
67
|
});
|
|
@@ -59,14 +59,12 @@ export const newLeaf = defineLeaf({
|
|
|
59
59
|
],
|
|
60
60
|
output: [
|
|
61
61
|
{ name: 'profile_id', type: 'string', required: true, constraint: 'Stable directory id (`<slug>-<shortid>`). Pass this, or the name, to every other `profile` verb and to `--profile` elsewhere.' },
|
|
62
|
-
{ name: 'name', type: 'string', required: true, constraint: 'The manifest name as given.' },
|
|
63
62
|
{ name: 'path', type: 'string', required: true, constraint: 'Absolute path to the profile directory.' },
|
|
64
63
|
{ name: 'projects', type: 'ProfileProject[]', required: true, constraint: 'Explicit `{path, memory}` project relationships in manifest order. `path` defines purview; `memory` caps automatic boot and workspace-open disclosure. Empty when --project was omitted.' },
|
|
65
64
|
{ name: 'home', type: 'string | null', required: true, constraint: 'Directory the profile\u2019s nodes are pinned to — the initial project, or null when none was given.' },
|
|
66
65
|
{ name: 'default_kind', type: 'string | null', required: true, constraint: 'Stored default persona kind, or null when node creates default to general.' },
|
|
67
66
|
{ name: 'metadata', type: 'object', required: true, constraint: 'Stored metadata map; empty when --meta was omitted.' },
|
|
68
67
|
{ name: 'created_at', type: 'string', required: true, constraint: 'ISO 8601 creation timestamp.' },
|
|
69
|
-
{ name: 'follow_up', type: 'string', required: true, constraint: 'Concrete next commands.' },
|
|
70
68
|
],
|
|
71
69
|
outputKind: 'object',
|
|
72
70
|
effects: ['Creates `<profile-dir>/profile.json` and `<profile-dir>/memory/` (the fixed root dir when `--root`).'],
|
|
@@ -85,14 +83,12 @@ export const newLeaf = defineLeaf({
|
|
|
85
83
|
const { profileId, manifest } = ensureRootProfile();
|
|
86
84
|
return {
|
|
87
85
|
profile_id: profileId,
|
|
88
|
-
name: manifest.name,
|
|
89
86
|
path: profileRoot(profileId),
|
|
90
87
|
projects: manifest.projects,
|
|
91
88
|
home: manifest.home,
|
|
92
89
|
default_kind: manifest.default_kind ?? null,
|
|
93
90
|
metadata: manifest.metadata ?? {},
|
|
94
91
|
created_at: manifest.created_at,
|
|
95
|
-
follow_up: `Root profile ensured. Spawn nodes under it with \`--profile ${profileId}\`, or widen its purview and choose its automatic memory disclosure cap with \`crtr profile project add ${profileId} --dir <path> --memory <none|name|preview|content>\`.`,
|
|
96
92
|
};
|
|
97
93
|
}
|
|
98
94
|
if (name === undefined)
|
|
@@ -108,14 +104,12 @@ export const newLeaf = defineLeaf({
|
|
|
108
104
|
});
|
|
109
105
|
return {
|
|
110
106
|
profile_id: profileId,
|
|
111
|
-
name: manifest.name,
|
|
112
107
|
path: profileRoot(profileId),
|
|
113
108
|
projects: manifest.projects,
|
|
114
109
|
home: manifest.home,
|
|
115
110
|
default_kind: manifest.default_kind ?? null,
|
|
116
111
|
metadata: manifest.metadata ?? {},
|
|
117
112
|
created_at: manifest.created_at,
|
|
118
|
-
follow_up: `Show it with \`crtr profile show ${profileId}\`, add purview and choose its automatic memory disclosure cap with \`crtr profile project add ${profileId} --dir <path> --memory <none|name|preview|content>\`, or list every profile with \`crtr profile list\`.`,
|
|
119
113
|
};
|
|
120
114
|
},
|
|
121
115
|
});
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { defineLeaf } from '../../core/command.js';
|
|
2
|
-
import {
|
|
2
|
+
import { resolveProfileOperand, pauseProfile, resumeProfile } from '../../core/profiles/manifest.js';
|
|
3
3
|
const profileParam = {
|
|
4
4
|
kind: 'positional',
|
|
5
5
|
name: 'profile',
|
|
6
6
|
required: true,
|
|
7
|
-
constraint: '
|
|
7
|
+
constraint: 'Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr.',
|
|
8
8
|
};
|
|
9
9
|
export const pauseLeaf = defineLeaf({
|
|
10
10
|
name: 'pause',
|
|
@@ -17,18 +17,16 @@ export const pauseLeaf = defineLeaf({
|
|
|
17
17
|
output: [
|
|
18
18
|
{ name: 'profile_id', type: 'string', required: true, constraint: 'Stable directory id.' },
|
|
19
19
|
{ name: 'paused_at', type: 'string', required: true, constraint: 'ISO 8601 timestamp when the profile became inert.' },
|
|
20
|
-
{ name: 'follow_up', type: 'string', required: true, constraint: 'Concrete resume command.' },
|
|
21
20
|
],
|
|
22
21
|
outputKind: 'object',
|
|
23
22
|
effects: ['Writes `paused_at` to the profile manifest. Existing brokers continue their current turn; queued inbox messages do not revive nodes until resume.'],
|
|
24
23
|
},
|
|
25
24
|
run: async (input) => {
|
|
26
|
-
const { profileId } =
|
|
25
|
+
const { profileId } = resolveProfileOperand(input['profile']);
|
|
27
26
|
const { manifest } = pauseProfile(profileId);
|
|
28
27
|
return {
|
|
29
28
|
profile_id: profileId,
|
|
30
29
|
paused_at: manifest.paused_at,
|
|
31
|
-
follow_up: `Resume it with \`crtr profile resume ${profileId}\`.`,
|
|
32
30
|
};
|
|
33
31
|
},
|
|
34
32
|
});
|
|
@@ -43,18 +41,16 @@ export const resumeLeaf = defineLeaf({
|
|
|
43
41
|
output: [
|
|
44
42
|
{ name: 'profile_id', type: 'string', required: true, constraint: 'Stable directory id.' },
|
|
45
43
|
{ name: 'paused_at', type: 'null', required: true, constraint: 'Always null after resume; null means active.' },
|
|
46
|
-
{ name: 'follow_up', type: 'string', required: true, constraint: 'Concrete next command.' },
|
|
47
44
|
],
|
|
48
45
|
outputKind: 'object',
|
|
49
46
|
effects: ['Clears `paused_at` in the profile manifest. Future creates and revives are allowed.'],
|
|
50
47
|
},
|
|
51
48
|
run: async (input) => {
|
|
52
|
-
const { profileId } =
|
|
49
|
+
const { profileId } = resolveProfileOperand(input['profile']);
|
|
53
50
|
const { manifest } = resumeProfile(profileId);
|
|
54
51
|
return {
|
|
55
52
|
profile_id: profileId,
|
|
56
53
|
paused_at: manifest.paused_at,
|
|
57
|
-
follow_up: `Inspect it with \`crtr profile show ${profileId}\`.`,
|
|
58
54
|
};
|
|
59
55
|
},
|
|
60
56
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// `crtr profile project` manages purview relationships and their automatic-memory caps.
|
|
2
2
|
import { defineLeaf, defineBranch } from '../../core/command.js';
|
|
3
|
-
import { addProfileProject, removeProfileProject,
|
|
3
|
+
import { addProfileProject, removeProfileProject, resolveProfileOperand } from '../../core/profiles/manifest.js';
|
|
4
4
|
import { PROFILE_PROJECT_MEMORY_VALUES } from '../../api/dto/profiles.js';
|
|
5
5
|
const addLeaf = defineLeaf({
|
|
6
6
|
name: 'add',
|
|
@@ -14,7 +14,7 @@ const addLeaf = defineLeaf({
|
|
|
14
14
|
kind: 'positional',
|
|
15
15
|
name: 'profile',
|
|
16
16
|
required: true,
|
|
17
|
-
constraint: '
|
|
17
|
+
constraint: 'Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr.',
|
|
18
18
|
},
|
|
19
19
|
{
|
|
20
20
|
kind: 'flag',
|
|
@@ -43,13 +43,12 @@ const addLeaf = defineLeaf({
|
|
|
43
43
|
{ name: 'profile_id', type: 'string', required: true, constraint: 'Stable directory id.' },
|
|
44
44
|
{ name: 'projects', type: 'ProfileProject[]', required: true, constraint: 'The updated `{path, memory}` relationships in manifest order. `path` defines purview; `memory` caps automatic boot and workspace-open disclosure.' },
|
|
45
45
|
{ name: 'home', type: 'string | null', required: true, constraint: "The profile's home directory after the change." },
|
|
46
|
-
{ name: 'follow_up', type: 'string', required: true, constraint: 'Concrete next commands.' },
|
|
47
46
|
],
|
|
48
47
|
outputKind: 'object',
|
|
49
48
|
effects: ["Appends a new project relationship or updates an existing relationship’s `memory` in the profile manifest, and rewrites `home` when --home is given. Purview follows `path`; `memory` caps automatic boot and workspace-open disclosure. Invalidates the process scope cache."],
|
|
50
49
|
},
|
|
51
50
|
run: async (input) => {
|
|
52
|
-
const { profileId } =
|
|
51
|
+
const { profileId } = resolveProfileOperand(input['profile']);
|
|
53
52
|
const { manifest } = addProfileProject(profileId, input['dir'], {
|
|
54
53
|
memory: input['memory'],
|
|
55
54
|
home: input['home'] === true,
|
|
@@ -58,7 +57,6 @@ const addLeaf = defineLeaf({
|
|
|
58
57
|
profile_id: profileId,
|
|
59
58
|
projects: manifest.projects,
|
|
60
59
|
home: manifest.home,
|
|
61
|
-
follow_up: `Show the full manifest with \`crtr profile show ${profileId}\`.`,
|
|
62
60
|
};
|
|
63
61
|
},
|
|
64
62
|
});
|
|
@@ -74,7 +72,7 @@ const removeLeaf = defineLeaf({
|
|
|
74
72
|
kind: 'positional',
|
|
75
73
|
name: 'profile',
|
|
76
74
|
required: true,
|
|
77
|
-
constraint: '
|
|
75
|
+
constraint: 'Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr.',
|
|
78
76
|
},
|
|
79
77
|
{
|
|
80
78
|
kind: 'flag',
|
|
@@ -88,19 +86,17 @@ const removeLeaf = defineLeaf({
|
|
|
88
86
|
{ name: 'profile_id', type: 'string', required: true, constraint: 'Stable directory id.' },
|
|
89
87
|
{ name: 'projects', type: 'ProfileProject[]', required: true, constraint: 'The updated `{path, memory}` relationships in manifest order.' },
|
|
90
88
|
{ name: 'home', type: 'string | null', required: true, constraint: "The profile's home directory after the change." },
|
|
91
|
-
{ name: 'follow_up', type: 'string', required: true, constraint: 'Concrete next commands.' },
|
|
92
89
|
],
|
|
93
90
|
outputKind: 'object',
|
|
94
91
|
effects: ["Removes a project relationship from the profile manifest, re-pointing `home` when that entry was it. This narrows purview and removes its automatic memory disclosure cap. Invalidates the process scope cache."],
|
|
95
92
|
},
|
|
96
93
|
run: async (input) => {
|
|
97
|
-
const { profileId } =
|
|
94
|
+
const { profileId } = resolveProfileOperand(input['profile']);
|
|
98
95
|
const { manifest } = removeProfileProject(profileId, input['dir']);
|
|
99
96
|
return {
|
|
100
97
|
profile_id: profileId,
|
|
101
98
|
projects: manifest.projects,
|
|
102
99
|
home: manifest.home,
|
|
103
|
-
follow_up: `Show the full manifest with \`crtr profile show ${profileId}\`.`,
|
|
104
100
|
};
|
|
105
101
|
},
|
|
106
102
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineLeaf } from '../../core/command.js';
|
|
2
|
-
import {
|
|
2
|
+
import { resolveProfileOperand, renameProfile } from '../../core/profiles/manifest.js';
|
|
3
3
|
export const renameLeaf = defineLeaf({
|
|
4
4
|
name: 'rename',
|
|
5
5
|
description: "change a profile's display name",
|
|
@@ -12,7 +12,7 @@ export const renameLeaf = defineLeaf({
|
|
|
12
12
|
kind: 'positional',
|
|
13
13
|
name: 'profile',
|
|
14
14
|
required: true,
|
|
15
|
-
constraint: '
|
|
15
|
+
constraint: 'Profile id or manifest name (the CURRENT name, before this rename); a close-enough name resolves to the nearest profile, reported on stderr.',
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
18
|
kind: 'flag',
|
|
@@ -24,19 +24,15 @@ export const renameLeaf = defineLeaf({
|
|
|
24
24
|
],
|
|
25
25
|
output: [
|
|
26
26
|
{ name: 'profile_id', type: 'string', required: true, constraint: 'Stable directory id — unchanged by this leaf.' },
|
|
27
|
-
{ name: 'name', type: 'string', required: true, constraint: 'The new manifest name.' },
|
|
28
|
-
{ name: 'follow_up', type: 'string', required: true, constraint: 'Concrete next commands.' },
|
|
29
27
|
],
|
|
30
28
|
outputKind: 'object',
|
|
31
29
|
effects: ["Changes the profile manifest's `name` field. Invalidates the process scope cache."],
|
|
32
30
|
},
|
|
33
31
|
run: async (input) => {
|
|
34
|
-
const { profileId } =
|
|
32
|
+
const { profileId } = resolveProfileOperand(input['profile']);
|
|
35
33
|
const { manifest } = renameProfile(profileId, input['name']);
|
|
36
34
|
return {
|
|
37
35
|
profile_id: profileId,
|
|
38
|
-
name: manifest.name,
|
|
39
|
-
follow_up: `Show the full manifest with \`crtr profile show ${profileId}\`.`,
|
|
40
36
|
};
|
|
41
37
|
},
|
|
42
38
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { defineLeaf } from '../../core/command.js';
|
|
4
|
-
import {
|
|
4
|
+
import { resolveProfileOperand, profileRoot, sanitizeProfileMetadata } from '../../core/profiles/manifest.js';
|
|
5
5
|
import { CONFIG_FILE } from '../../types.js';
|
|
6
6
|
export const showLeaf = defineLeaf({
|
|
7
7
|
name: 'show',
|
|
@@ -15,7 +15,7 @@ export const showLeaf = defineLeaf({
|
|
|
15
15
|
kind: 'positional',
|
|
16
16
|
name: 'profile',
|
|
17
17
|
required: true,
|
|
18
|
-
constraint: '
|
|
18
|
+
constraint: 'Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr. A name shared by several profiles fails listing every matching id.',
|
|
19
19
|
},
|
|
20
20
|
],
|
|
21
21
|
output: [
|
|
@@ -37,7 +37,7 @@ export const showLeaf = defineLeaf({
|
|
|
37
37
|
effects: ['None. Read-only.'],
|
|
38
38
|
},
|
|
39
39
|
run: async (input) => {
|
|
40
|
-
const { profileId, manifest } =
|
|
40
|
+
const { profileId, manifest } = resolveProfileOperand(input['profile']);
|
|
41
41
|
const configPath = join(profileRoot(profileId), CONFIG_FILE);
|
|
42
42
|
return {
|
|
43
43
|
profile_id: profileId,
|