@sabaiway/agent-workflow-kit 14.25.1 → 14.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,19 +1,20 @@
1
1
  import { join, resolve } from 'node:path';
2
2
  import { dirCovers } from './declared-paths.mjs';
3
- import { claudeDirOf, skillTargets } from './jev-facts.mjs';
3
+ import { claudeDirOf, quoteArg, skillTargets } from './jev-facts.mjs';
4
4
  import { targetsFor } from './jev-connect.mjs';
5
5
 
6
- export const LANE_CONSOLE = 'console';
7
6
  export const LANE_CHAT = 'chat';
7
+ export const LANE_HARNESS = 'harness';
8
+ export const LANE_USER = 'user';
8
9
 
9
10
  export const VARIANT_LANES = Object.freeze({
10
- 'velocity-core': LANE_CONSOLE,
11
- 'kit-tools-tier': LANE_CONSOLE,
12
- 'bridge-tier': LANE_CONSOLE,
11
+ 'velocity-core': LANE_HARNESS,
12
+ 'kit-tools-tier': LANE_HARNESS,
13
+ 'bridge-tier': LANE_HARNESS,
13
14
  'autonomy-policy': LANE_CHAT,
14
- 'autonomy-render': LANE_CONSOLE,
15
- 'sandbox-provision': LANE_CONSOLE,
16
- 'sandbox-provision.installable': LANE_CONSOLE,
15
+ 'autonomy-render': LANE_HARNESS,
16
+ 'sandbox-provision': LANE_USER,
17
+ 'sandbox-provision.installable': LANE_USER,
17
18
  'review-recipe': LANE_CHAT,
18
19
  'gates-declaration': LANE_CHAT,
19
20
  'gates-inert': LANE_CHAT,
@@ -24,19 +25,19 @@ export const VARIANT_LANES = Object.freeze({
24
25
  'source-size.unminted': LANE_CHAT,
25
26
  'source-size.adopted-elsewhere': LANE_CHAT,
26
27
  'source-size.id-squatter': LANE_CHAT,
27
- 'gate-hook': LANE_CONSOLE,
28
- 'gate-hook.marker-stale': LANE_CONSOLE,
29
- 'commit-guard': LANE_CONSOLE,
30
- enforcement: LANE_CONSOLE,
28
+ 'gate-hook': LANE_HARNESS,
29
+ 'gate-hook.marker-stale': LANE_USER,
30
+ 'commit-guard': LANE_USER,
31
+ enforcement: LANE_USER,
31
32
  'read-lane': LANE_CHAT,
32
- 'read-lane.stale': LANE_CONSOLE,
33
- 'read-lane.missing': LANE_CONSOLE,
34
- 'state-block': LANE_CONSOLE,
35
- 'mcp-channel': LANE_CONSOLE,
36
- 'mcp-channel.differing': LANE_CONSOLE,
37
- agents: LANE_CONSOLE,
38
- 'executor-vehicle': LANE_CONSOLE,
39
- 'family-freshness': LANE_CONSOLE,
33
+ 'read-lane.stale': LANE_USER,
34
+ 'read-lane.missing': LANE_HARNESS,
35
+ 'state-block': LANE_USER,
36
+ 'mcp-channel': LANE_HARNESS,
37
+ 'mcp-channel.differing': LANE_HARNESS,
38
+ agents: LANE_HARNESS,
39
+ 'executor-vehicle': LANE_HARNESS,
40
+ 'family-freshness': LANE_USER,
40
41
  'adr-store-migration': LANE_CHAT,
41
42
  'sandbox-masks': LANE_CHAT,
42
43
  'sandbox-masks.unfenced-mount': LANE_CHAT,
@@ -44,9 +45,9 @@ export const VARIANT_LANES = Object.freeze({
44
45
  'worktrees-dir': LANE_CHAT,
45
46
  'spec-adoption': LANE_CHAT,
46
47
  'profile-gap': LANE_CHAT,
47
- 'jev-connect': LANE_CONSOLE,
48
- 'jev-skill': LANE_CONSOLE,
49
- 'jev-skill.earlier': LANE_CONSOLE,
48
+ 'jev-connect': LANE_USER,
49
+ 'jev-skill': LANE_HARNESS,
50
+ 'jev-skill.earlier': LANE_HARNESS,
50
51
  'spec-adoption.adopting': LANE_CHAT,
51
52
  });
52
53
 
@@ -78,8 +79,6 @@ export const isProtectedPath = (abs, { root, home, hooksDir }) => {
78
79
  || [...PROTECTED_DIRS.map((dir) => join(project, dir)), hooks].some((dir) => dirCovers(dir, path));
79
80
  };
80
81
 
81
- const ROUTE = "applies at your next npx @sabaiway/agent-workflow-kit@latest init, run from this project's folder";
82
- const RESTART = '; if init reports it not pending, restart the agent from that console';
83
82
  const SETTINGS_WRITES = [SETTINGS_PATH];
84
83
  const HOOK_WRITES = [join('.claude', 'hooks', 'agent-workflow-gates.mjs'), ...SETTINGS_WRITES];
85
84
  const MCP_WRITES = ['.mcp.json', ...SETTINGS_WRITES];
@@ -98,12 +97,16 @@ const getStartupPaths = ({ env, home, platform }) => targetsFor({
98
97
  platform,
99
98
  }).filter(({ path }) => path !== null).map(({ path }) => path);
100
99
 
101
- const createForm = (file, preview, apply, writes, restart = false) => Object.freeze({
100
+ const formatCommand = (argv) => argv.map(quoteArg).join(' ');
101
+ const TERMINAL_STEP = 'run in a terminal of your own: ';
102
+
103
+ const createForm = (file, preview, apply, writes, envDependent = false, userStep = null) => Object.freeze({
102
104
  file,
103
105
  preview,
104
106
  apply,
105
107
  writes,
106
- route: restart ? ROUTE + RESTART : ROUTE,
108
+ envDependent,
109
+ userStep,
107
110
  });
108
111
 
109
112
  const CORE_FORM = createForm('velocity-profile.mjs', ['--cwd', '<root>'], ['--apply', '--cwd', '<root>'], SETTINGS_WRITES);
@@ -126,11 +129,17 @@ const FORMS = Object.freeze({
126
129
  ['--replace', '--cwd', '<root>'], ['--replace', '--apply', '--cwd', '<root>'], MCP_WRITES),
127
130
  agents: AGENT_FORM,
128
131
  'executor-vehicle': AGENT_FORM,
129
- 'sandbox-provision.installable': createForm('autonomy-doctor.mjs', [], ['--apply', '<tuple>'], [], true),
132
+ 'sandbox-provision.installable': createForm('autonomy-doctor.mjs', [], ['--apply', '<tuple>'], [], true,
133
+ (facts, argv) => 'your own step (a sudo install; the doctor prints the --apply line to run next) — '
134
+ + `${TERMINAL_STEP}cd ${quoteArg(facts.root)} && ${formatCommand(argv.preview)}`),
130
135
  'jev-skill': SKILL_FORM,
131
136
  'jev-skill.earlier': SKILL_FORM,
132
- 'jev-connect': createForm('jev-connect.mjs', null, [], getStartupPaths, true),
133
- 'family-freshness': { route: ROUTE },
137
+ 'jev-connect': createForm('jev-connect.mjs', null, [], getStartupPaths, true,
138
+ (facts, argv) => 'your own step — it asks for the key in your terminal and the key never goes into the chat — '
139
+ + `${TERMINAL_STEP}${formatCommand(argv.apply)}`),
140
+ 'family-freshness': Object.freeze({
141
+ userStep: () => `your own step — ${TERMINAL_STEP}${formatCommand(['npx', '@sabaiway/agent-workflow-kit@latest', 'init'])}`,
142
+ }),
134
143
  'sandbox-provision': null,
135
144
  'commit-guard': null,
136
145
  'gate-hook.marker-stale': null,
@@ -165,7 +174,22 @@ export const writesOf = (variant, facts) => {
165
174
  return form.writes.map((path) => join(facts.root, path));
166
175
  };
167
176
 
168
- export const routeLine = (variant) => {
177
+ export const isEnvDependent = (variant) => {
169
178
  laneOf(variant);
170
- return FORMS[variant]?.route ?? null;
179
+ return FORMS[variant]?.envDependent === true;
180
+ };
181
+
182
+ export const applySlot = (variant, facts) => {
183
+ const lane = laneOf(variant);
184
+ const form = FORMS[variant];
185
+ if (lane === LANE_HARNESS) {
186
+ const args = ['node', join(facts.toolsDir, 'apply-danger-check.mjs'), '--variant', variant, '--cwd', facts.root];
187
+ const skillArgs = form === SKILL_FORM ? form.preview.map((arg) => resolveArgument(arg, facts)) : [];
188
+ const check = formatCommand([...args, ...skillArgs]);
189
+ return { check, apply: `${check} --apply --expect <digest>` };
190
+ }
191
+ if (lane === LANE_USER && form?.userStep) {
192
+ return { check: null, apply: form.userStep(facts, consoleArgv(variant, facts)) };
193
+ }
194
+ return null;
171
195
  };