@elevasis/sdk 0.5.15 → 0.5.17

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/index.d.ts CHANGED
@@ -488,6 +488,8 @@ interface SerializedAgentDefinition {
488
488
  version: string;
489
489
  type: 'agent';
490
490
  status: 'dev' | 'prod';
491
+ /** Whether this resource is archived and should be excluded from registration and deployment */
492
+ archived?: boolean;
491
493
  systemPrompt: string;
492
494
  constraints?: {
493
495
  maxIterations?: number;
@@ -503,7 +505,7 @@ interface SerializedAgentDefinition {
503
505
  model: string;
504
506
  apiKey: string;
505
507
  temperature: number;
506
- maxTokens: number;
508
+ maxOutputTokens: number;
507
509
  topP?: number;
508
510
  modelOptions?: Record<string, unknown>;
509
511
  };
@@ -541,6 +543,8 @@ interface SerializedWorkflowDefinition {
541
543
  version: string;
542
544
  type: 'workflow';
543
545
  status: 'dev' | 'prod';
546
+ /** Whether this resource is archived and should be excluded from registration and deployment */
547
+ archived?: boolean;
544
548
  };
545
549
  entryPoint: string;
546
550
  steps: Array<{
@@ -653,7 +657,8 @@ interface ModelConfig {
653
657
  provider: 'openai' | 'anthropic' | 'openrouter' | 'google' | 'mock';
654
658
  apiKey: string;
655
659
  temperature?: number;
656
- maxTokens?: number;
660
+ /** Maximum output tokens per LLM call. NOT the model's context window — see ModelInfo.maxTokens for that. */
661
+ maxOutputTokens?: number;
657
662
  topP?: number;
658
663
  /**
659
664
  * Model-specific options (flat structure)
@@ -783,7 +788,8 @@ interface LLMMessage {
783
788
  interface LLMGenerateRequest {
784
789
  messages: LLMMessage[];
785
790
  responseSchema: unknown;
786
- maxTokens?: number;
791
+ /** Maximum output tokens per LLM call. NOT the model's context window — see ModelInfo.maxTokens for that. */
792
+ maxOutputTokens?: number;
787
793
  temperature?: number;
788
794
  topP?: number;
789
795
  signal?: AbortSignal;
@@ -5650,12 +5656,27 @@ interface ExecutionMetadata {
5650
5656
  * Unified message event type - covers all message types in sessions
5651
5657
  * Replaces separate SessionTurnMessages and AgentActivityEvent mechanisms
5652
5658
  */
5659
+ /**
5660
+ * Structured action metadata attached to assistant messages.
5661
+ * Frontend reads this instead of parsing text prefixes.
5662
+ */
5663
+ type AssistantAction = {
5664
+ kind: 'navigate';
5665
+ path: string;
5666
+ reason: string;
5667
+ } | {
5668
+ kind: 'update_filters';
5669
+ timeRange: string | null;
5670
+ statusFilter: string | null;
5671
+ searchQuery: string | null;
5672
+ };
5653
5673
  type MessageEvent = {
5654
5674
  type: 'user_message';
5655
5675
  text: string;
5656
5676
  } | {
5657
5677
  type: 'assistant_message';
5658
5678
  text: string;
5679
+ _action?: AssistantAction;
5659
5680
  } | {
5660
5681
  type: 'agent:started';
5661
5682
  } | {
@@ -5791,6 +5812,8 @@ interface ResourceDefinition {
5791
5812
  sessionCapable?: boolean;
5792
5813
  /** Whether the resource is local (monorepo) or remote (externally deployed) */
5793
5814
  origin?: 'local' | 'remote';
5815
+ /** Whether this resource is archived and should be excluded from registration and deployment */
5816
+ archived?: boolean;
5794
5817
  }
5795
5818
  /**
5796
5819
  * Domain definition for Command View filtering
package/dist/index.js CHANGED
@@ -197,7 +197,7 @@ var GPT5ConfigSchema = z.object({
197
197
  apiKey: z.string(),
198
198
  temperature: z.literal(1),
199
199
  // Required to be exactly 1
200
- maxTokens: z.number().min(4e3).optional(),
200
+ maxOutputTokens: z.number().min(4e3).optional(),
201
201
  topP: z.number().min(0).max(1).optional(),
202
202
  modelOptions: GPT5OptionsSchema.optional()
203
203
  });
@@ -206,7 +206,7 @@ var MockConfigSchema = z.object({
206
206
  provider: z.enum(["mock"]),
207
207
  apiKey: z.string(),
208
208
  temperature: z.number().min(0).max(2).optional(),
209
- maxTokens: z.number().min(500).optional(),
209
+ maxOutputTokens: z.number().min(500).optional(),
210
210
  topP: z.number().min(0).max(1).optional(),
211
211
  modelOptions: z.object({}).strict().optional()
212
212
  // No options supported
@@ -226,7 +226,7 @@ var OpenRouterConfigSchema = z.object({
226
226
  provider: z.literal("openrouter"),
227
227
  apiKey: z.string(),
228
228
  temperature: z.number().min(0).max(2).optional(),
229
- maxTokens: z.number().min(500).optional(),
229
+ maxOutputTokens: z.number().min(500).optional(),
230
230
  topP: z.number().min(0).max(1).optional(),
231
231
  modelOptions: OpenRouterOptionsSchema.optional()
232
232
  });
@@ -240,7 +240,7 @@ var GoogleConfigSchema = z.object({
240
240
  apiKey: z.string(),
241
241
  temperature: z.literal(1).optional(),
242
242
  // Must be 1 for Gemini 3 (changing degrades performance)
243
- maxTokens: z.number().min(500).optional(),
243
+ maxOutputTokens: z.number().min(500).optional(),
244
244
  topP: z.number().min(0).max(1).optional(),
245
245
  modelOptions: GoogleOptionsSchema.optional()
246
246
  });
@@ -250,7 +250,7 @@ var AnthropicConfigSchema = z.object({
250
250
  provider: z.literal("anthropic"),
251
251
  apiKey: z.string(),
252
252
  temperature: z.number().min(0).max(1).optional(),
253
- maxTokens: z.number().min(1e3).optional(),
253
+ maxOutputTokens: z.number().min(1e3).optional(),
254
254
  // Anthropic requires max_tokens
255
255
  topP: z.number().min(0).max(1).optional(),
256
256
  modelOptions: AnthropicOptionsSchema.optional()
@@ -3160,6 +3160,17 @@ function buildEdges(resources) {
3160
3160
  }
3161
3161
 
3162
3162
  // ../core/src/platform/registry/resource-registry.ts
3163
+ function filterArchived(org) {
3164
+ return {
3165
+ ...org,
3166
+ workflows: org.workflows?.filter((w) => !w.config.archived),
3167
+ agents: org.agents?.filter((a) => !a.config.archived),
3168
+ triggers: org.triggers?.filter((t) => !t.archived),
3169
+ integrations: org.integrations?.filter((i) => !i.archived),
3170
+ externalResources: org.externalResources?.filter((e) => !e.archived),
3171
+ humanCheckpoints: org.humanCheckpoints?.filter((h) => !h.archived)
3172
+ };
3173
+ }
3163
3174
  var ResourceRegistry = class {
3164
3175
  constructor(registry) {
3165
3176
  this.registry = registry;
@@ -3291,6 +3302,7 @@ var ResourceRegistry = class {
3291
3302
  * @throws Error if incoming deployment contains duplicate resourceIds
3292
3303
  */
3293
3304
  registerOrganization(orgName, org, remote) {
3305
+ org = filterArchived(org);
3294
3306
  const incomingWorkflowIds = (org.workflows ?? []).map((w) => w.config.resourceId);
3295
3307
  const incomingAgentIds = (org.agents ?? []).map((a) => a.config.resourceId);
3296
3308
  const incomingIds = [...incomingWorkflowIds, ...incomingAgentIds];
@@ -3352,6 +3364,7 @@ var ResourceRegistry = class {
3352
3364
  * @param org - Resource definitions with real handlers (not stubs)
3353
3365
  */
3354
3366
  registerStaticResources(orgName, org) {
3367
+ org = filterArchived(org);
3355
3368
  const incomingWorkflowIds = (org.workflows ?? []).map((w) => w.config.resourceId);
3356
3369
  const incomingAgentIds = (org.agents ?? []).map((a) => a.config.resourceId);
3357
3370
  const incomingIds = [...incomingWorkflowIds, ...incomingAgentIds];
package/dist/templates.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // package.json
2
2
 
3
3
  // src/cli/commands/templates/core/workspace.ts
4
- var TEMPLATE_VERSION = 28;
4
+ var TEMPLATE_VERSION = 29;
5
5
  function configTemplate() {
6
6
  return `import type { ElevasConfig } from '@elevasis/sdk'
7
7
 
@@ -104,8 +104,8 @@ process.stdin.on('end', () => {
104
104
  function claudeSdkBoundaryHookTemplate() {
105
105
  return String.raw`#!/usr/bin/env node
106
106
  // enforce-sdk-boundary.mjs
107
- // Blocks gh CLI, destructive git operations, and file writes outside the project root.
108
- // Allows git add, commit, push, pull, fetch -- used by /meta deploy.
107
+ // Blocks file modifications (Write, Edit, MultiEdit, destructive Bash) outside the project root.
108
+ // Git, gh, and other CLI tools are NOT blocked -- the agent can use them freely.
109
109
 
110
110
  import { resolve, normalize } from "node:path";
111
111
  import { appendFileSync, mkdirSync } from "node:fs";
@@ -150,44 +150,6 @@ try {
150
150
  if (input.tool_name === "Bash") {
151
151
  const cmd = input.tool_input?.command ?? "";
152
152
 
153
- // GitHub CLI -- blocked (affects shared remote state, user-initiated only)
154
- if (/\bgh\b/.test(cmd)) {
155
- deny(
156
- "BLOCKED: GitHub CLI (gh) command detected.\n" +
157
- "WHY: GitHub CLI operations affect shared remote state (PRs, issues, releases). These must be user-initiated.\n" +
158
- "INSTEAD: Ask the user to run this gh command manually."
159
- );
160
- process.exit(0);
161
- }
162
-
163
- // Destructive git -- blocked
164
- if (/(?<!-)\bgit\s+reset\b/.test(cmd) && /--hard/.test(cmd)) {
165
- deny(
166
- "BLOCKED: git reset --hard detected.\n" +
167
- "WHY: Hard resets destroy uncommitted work and cannot be undone. This must be user-initiated.\n" +
168
- "INSTEAD: Ask the user to run this git command manually."
169
- );
170
- process.exit(0);
171
- }
172
-
173
- if (/(?<!-)\bgit\s+clean\b/.test(cmd) && /-[a-zA-Z]*f/.test(cmd)) {
174
- deny(
175
- "BLOCKED: git clean -f detected.\n" +
176
- "WHY: Force-cleaning the working tree permanently removes untracked files. This must be user-initiated.\n" +
177
- "INSTEAD: Ask the user to run this git command manually."
178
- );
179
- process.exit(0);
180
- }
181
-
182
- if (/(?<!-)\bgit\s+(rebase|merge)\b/.test(cmd)) {
183
- deny(
184
- "BLOCKED: git rebase/merge detected.\n" +
185
- "WHY: Rebase and merge rewrite history or combine branches in ways that require user judgment.\n" +
186
- "INSTEAD: Ask the user to run this git command manually."
187
- );
188
- process.exit(0);
189
- }
190
-
191
153
  // Path-scoped blocks -- destructive commands or redirects outside project root
192
154
  const winPaths = cmd.match(/(?<![A-Za-z])[A-Za-z]:[/\\][^\s"'|;&)]+/g) || [];
193
155
  const unixPaths = cmd.match(/(?<=\s|^|"|')\/[^\s"'|;&)]+/g) || [];
@@ -370,7 +332,7 @@ For detailed per-dimension adaptation rules, read
370
332
  | --- | --- |
371
333
  | \`/meta\` | Project lifecycle: init, status, fix, deploy, health |
372
334
  | \`/docs\` | Browse, create, and verify permanent documentation |
373
- | \`/work\` | Task tracking: create, save, resume, complete |
335
+ | \`/work\` | Task tracking: auto-detects intent (create, save, resume); suggests complete |
374
336
  | \`/tutorial\` | Progressive learning path (21 items across 4 sections) |
375
337
 
376
338
  ## Skills
@@ -602,43 +564,46 @@ Observation focus: full lifecycle coverage, pipeline internals.
602
564
  **Item 4: /work and /docs**
603
565
 
604
566
  When automation is none:
605
- "You can ask the assistant to track work across conversations. When you start something
606
- complex, use /work create to save your place. Next session, /work resume picks up where
607
- you left off." Walk through the concept without deep command details. Then introduce /docs:
608
- "When a task is finished, /work complete moves it to docs/ permanently. After that, /docs
609
- helps you find and read what's there -- like a notebook for your project." Run /docs (no
610
- args) to show the docs/ overview together.
611
- Verify: Create a task with \`/work create "practice task"\`, then run /work to see it listed.
567
+ "You can ask the assistant to track work across conversations. Just say /work and tell it
568
+ what you're working on -- it figures out the rest. It'll save your progress automatically,
569
+ and next session you just say /work to pick up where you left off." Walk through the
570
+ concept without deep command details. Then introduce /docs:
571
+ "When a task is done, the assistant will ask if you want to finalize it -- that moves it
572
+ to docs/ permanently. /docs helps you find and read what's there -- like a notebook for
573
+ your project." Run /docs (no args) to show the docs/ overview together.
574
+ Verify: Run \`/work\` and describe "practice task", see it created automatically.
612
575
  Then run /docs to see the docs/ structure.
613
576
  Observation focus: persistence concept, cross-session continuity, docs as permanent notes.
614
577
 
615
578
  When automation is low-code:
616
- Show /work operations: create (task doc with frontmatter + sections), save (updates
617
- Progress + Resume Context), resume (loads context for next session), complete (moves
618
- to permanent docs/).
579
+ Show /work as intent-driven: the agent detects whether to create, resume, or save based
580
+ on context. Create happens when you describe new work, resume when you pick an existing
581
+ task, save happens automatically when progress is made. Complete is the only action that
582
+ asks permission first.
619
583
  Then introduce /docs: "/docs is for permanent knowledge -- things that don't expire. Use
620
584
  /docs create to document a workflow or integration. Use /docs verify to check if your
621
585
  docs match the current code." Explain the boundary: /work manages in-progress/, /docs
622
586
  manages permanent docs/.
623
- Verify: Create a task with \`/work create "practice task"\`, run /work save, inspect the
624
- file. Then run /docs to browse docs/.
625
- Observation focus: task tracking workflow, /work vs /docs separation.
587
+ Verify: Run \`/work\` and describe "practice task", see auto-create. Make some changes,
588
+ then notice auto-save. Then run /docs to browse docs/.
589
+ Observation focus: intent-driven task tracking, /work vs /docs separation.
626
590
 
627
591
  When automation is custom:
628
592
  Read \`.claude/commands/work.md\`. Full /work coverage:
629
- /work create (kebab-case filename, frontmatter with status, Objective/Plan/Progress/
630
- Resume Context sections), /work save (Progress + Resume Context update), /work resume
631
- (multiple-task disambiguation), /work complete (moves to final location).
593
+ Intent detection table (list, create, resume, save auto-invoked; complete always suggests).
594
+ Task doc anatomy: kebab-case filename, frontmatter with status, Objective/Plan/Progress/
595
+ Resume Context sections. Auto-save behavior: triggers on heavy context, wrap-up signals,
596
+ 2+ steps completed. Resolution order for resume: number, keyword match, single in-progress.
632
597
  Then read \`.claude/commands/docs.md\`. Cover /docs operations:
633
598
  /docs (default): browse permanent docs/, categorized with read-only auto-generated files
634
599
  separate; /docs create: interview-driven, resource-aware doc creation from src/ code
635
600
  analysis; /docs verify: cross-references resource IDs, schema fields, platform tools in
636
601
  docs against src/ -- standalone analog of /meta fix step 5.
637
- Explain the relationship: /work owns docs/in-progress/ (task lifecycle), /work complete
602
+ Explain the relationship: /work owns docs/in-progress/ (task lifecycle), completing a task
638
603
  moves docs to permanent location, /docs browses and verifies what's there.
639
- Verify: Create a task doc, save progress, run /work complete to move it. Then run /docs
640
- to see it in the permanent docs/ listing.
641
- Observation focus: task doc anatomy, /work-to-/docs handoff, docs verification as standalone tool.
604
+ Verify: Create a task via /work, make progress, observe auto-save, then run /work complete
605
+ to move it. Run /docs to see it in the permanent docs/ listing.
606
+ Observation focus: intent detection, auto-save behavior, /work-to-/docs handoff, docs verification.
642
607
 
643
608
  **Item 5: Your First Custom Workflow**
644
609
 
@@ -1172,6 +1137,8 @@ function claudeWorkCommandTemplate() {
1172
1137
 
1173
1138
  You are a task tracking assistant for this Elevasis workspace. \`/work\` is the primary command for managing all work and projects.
1174
1139
 
1140
+ Your job is to **intelligently manage tasks without requiring the user to know subcommands**. Detect what the user needs from context and act accordingly.
1141
+
1175
1142
  ## Context
1176
1143
 
1177
1144
  Read \`docs/priorities.mdx\` if it exists for current priorities.
@@ -1191,9 +1158,25 @@ When scanning, treat \`index.mdx\` as the primary task doc for a directory.
1191
1158
 
1192
1159
  Enforce exactly three values in frontmatter: \`planned\`, \`in-progress\`, \`complete\`.
1193
1160
 
1194
- ## Operations
1161
+ ## Intent Detection
1162
+
1163
+ When \`/work\` is invoked (with or without arguments), detect intent from context:
1164
+
1165
+ | Signal | Action |
1166
+ |--------|--------|
1167
+ | No arguments, no active conversation context | **List** tasks, then let user pick |
1168
+ | User picks a number or names a task | **Resume** that task automatically |
1169
+ | User describes new work (not matching existing tasks) | **Create** a task doc automatically |
1170
+ | \`/work\` with a description that matches no existing task | **Create** automatically |
1171
+ | \`/work\` with a keyword/name matching an existing task | **Resume** automatically |
1172
+ | Conversation is getting heavy, user wrapping up, or 2+ steps completed | **Save** automatically |
1173
+ | All plan steps are COMPLETE | **Suggest** \`/work complete\` (never auto-invoke) |
1195
1174
 
1196
- ### No arguments (default) -- List and Pick
1175
+ **Key principle:** Create, save, and resume are auto-invoked. Complete always asks permission first.
1176
+
1177
+ ## Behaviors
1178
+
1179
+ ### List and Pick (default when no context)
1197
1180
 
1198
1181
  1. Scan \`docs/in-progress/\` recursively for \`.mdx\` files with \`status\` frontmatter
1199
1182
  2. For directories, read \`index.mdx\` as the primary task doc
@@ -1212,30 +1195,25 @@ Active Tasks
1212
1195
  3. [complete] CRM Integration
1213
1196
  Completed: 2026-03-03
1214
1197
 
1215
- Pick a task by number or name to resume, or say:
1216
- - "create" to start new work
1217
- - "complete <name>" to finish a task
1198
+ Pick a task by number or name, or describe new work to start.
1218
1199
  \`\`\`
1219
1200
 
1220
1201
  4. Cross-reference with \`docs/priorities.mdx\` if it exists
1221
- 5. When the user picks a number or describes a task in natural language, auto-invoke the **resume** flow on that task
1222
- 6. If no tasks found, suggest \`/work create\`
1202
+ 5. When the user picks a number or describes a task, auto-invoke the appropriate flow (resume or create)
1203
+ 6. If no tasks found, ask: "What are you trying to accomplish?"
1223
1204
 
1224
- ### \`create [description]\`
1205
+ ### Create (auto-invoked when new work detected)
1225
1206
 
1226
- Guided task creation with interview:
1227
-
1228
- 1. If no description given, ask: "What are you trying to accomplish?"
1229
- 2. Ask 2-3 focused questions:
1207
+ 1. If the user's intent is clear, skip the interview and create directly
1208
+ 2. If ambiguous, ask 1-2 focused questions:
1230
1209
  - "What does success look like?" (acceptance criteria)
1231
- - "Is this related to any existing work?" (scan \`docs/in-progress/\` and \`docs/\` for related topics)
1232
- - "Do we need to investigate anything first, or is the path clear?" (suggest investigation if needed)
1233
- 3. Determine directory placement:
1234
- - Scan \`docs/in-progress/\` for existing directories related to the topic
1210
+ - "Do we need to investigate anything first, or is the path clear?"
1211
+ 3. Scan \`docs/in-progress/\` for existing directories related to the topic
1212
+ 4. Determine directory placement:
1235
1213
  - If related to existing directory, create as a file within it
1236
1214
  - If new concept that may grow, create \`docs/in-progress/<slug>/index.mdx\`
1237
1215
  - If small/standalone, create \`docs/in-progress/<slug>.mdx\`
1238
- 4. Create the doc with \`status: planned\` and structured sections:
1216
+ 5. Create the doc with \`status: planned\` and structured sections:
1239
1217
 
1240
1218
  \`\`\`yaml
1241
1219
  ---
@@ -1247,15 +1225,20 @@ status: planned
1247
1225
 
1248
1226
  Sections: Objective (what and why), Plan (numbered steps), Progress (per-step tracking with PENDING markers), Resume Context (current state, key docs, "To continue" prompt).
1249
1227
 
1250
- 5. Update \`docs/priorities.mdx\` if it exists
1251
- 6. Report what was created with location and step count
1228
+ 6. Update \`docs/priorities.mdx\` if it exists
1229
+ 7. Report what was created with location and step count
1252
1230
 
1253
- ### \`save\`
1231
+ ### Save (auto-invoked when progress detected)
1254
1232
 
1255
- Update the current task doc's Progress and Resume Context:
1233
+ Auto-save triggers (do NOT ask, just save):
1234
+ - The conversation context is getting heavy (many tool calls, large file reads)
1235
+ - The user appears to be wrapping up (thanks, goodbye, switching topics)
1236
+ - Significant progress has been made (2+ steps completed without saving)
1237
+ - Before a context reset
1256
1238
 
1257
- 1. Identify the current task from conversation context (which in-progress doc was loaded/discussed)
1258
- 2. If not working on a tracked task, list available docs and ask which to save to, or offer to create a new one
1239
+ Save flow:
1240
+ 1. Identify the current task from conversation context
1241
+ 2. If not working on a tracked task, offer to create a new one
1259
1242
  3. Update Progress section:
1260
1243
  - Mark completed steps as \`COMPLETE\` with: what was done, key decisions, files changed
1261
1244
  - Mark current step as \`IN PROGRESS\` with current state
@@ -1265,15 +1248,13 @@ Update the current task doc's Progress and Resume Context:
1265
1248
  - Files Modified: table of file paths and descriptions of changes
1266
1249
  - Key docs to read on resume: file paths with why they matter
1267
1250
  - To continue: copy-pasteable prompt for the next session
1268
- 5. Set \`status\` appropriately (\`in-progress\` if ongoing, \`complete\` if all steps done)
1269
- 6. Report: task title, status, completed steps count, last step, and the resume command
1251
+ 5. Set \`status\` appropriately (\`in-progress\` if ongoing)
1252
+ 6. Briefly confirm: "Progress saved to {path}."
1270
1253
 
1271
- ### \`resume [name-or-number]\`
1272
-
1273
- Resume in-progress work. Designed for non-technical users who may not know file paths.
1254
+ ### Resume (auto-invoked when existing task detected)
1274
1255
 
1275
1256
  **Resolution order:**
1276
- 1. If a number is given (e.g., \`/work resume 2\`), map to the numbered list from the default list operation
1257
+ 1. If a number is given, map to the numbered list from the task list
1277
1258
  2. If a name/keyword is given, substring match against task titles and filenames in \`docs/in-progress/\`
1278
1259
  3. If no argument, scan for \`status: in-progress\` docs -- if one found, use it; if multiple, list and ask
1279
1260
  4. If multiple matches, list them and ask which to resume
@@ -1299,35 +1280,32 @@ Key context loaded:
1299
1280
  Ready to continue. {Copy of "To continue" prompt}
1300
1281
  \`\`\`
1301
1282
 
1302
- ### \`complete [name]\`
1283
+ ### Complete (NEVER auto-invoked -- always suggest)
1284
+
1285
+ When all plan steps are COMPLETE, suggest: "All steps for '{task}' look done. Want me to finalize it?"
1303
1286
 
1304
- Mark task complete, clean up, and move to permanent docs:
1287
+ Only proceed after explicit user confirmation. Then:
1305
1288
 
1306
- 1. Resolve target (same as resume: number, name, or scan for \`status: complete\`)
1307
- 2. **Validate readiness:** Check that all plan steps are marked COMPLETE. If not, warn and ask for confirmation.
1308
- 3. **Clean up the doc:**
1289
+ 1. **Validate readiness:** Check that all plan steps are marked COMPLETE. If not, warn and ask for confirmation.
1290
+ 2. **Clean up the doc:**
1309
1291
  - Strip \`## Resume Context\` section entirely (header through next \`##\` or EOF)
1310
1292
  - Strip progress markers: \`COMPLETE\`, \`IN PROGRESS\`, \`PENDING\` from step headings
1311
1293
  - Remove steps still marked PENDING entirely (header + body) -- they were never done
1312
1294
  - Remove \`status\` from frontmatter (keep \`title\` and \`description\`)
1313
1295
  - Target 200-400 lines; flag if result exceeds 500 lines
1314
- 4. **Determine destination:**
1296
+ 3. **Determine destination:**
1315
1297
  - Scan \`docs/\` (excluding \`docs/in-progress/\`) for existing directories related to this work
1316
1298
  - If a related directory exists, propose merging into it
1317
1299
  - If no related directory, propose \`docs/<slug>/\` or \`docs/<slug>.mdx\`
1318
1300
  - Present the proposed destination and ask user to confirm
1319
- 5. **Move the doc(s):**
1301
+ 4. **Move the doc(s):**
1320
1302
  - Single file: move from \`docs/in-progress/\` to destination
1321
1303
  - Directory: move entire directory
1322
- 6. **Verify and report:**
1304
+ 5. **Verify and report:**
1323
1305
  - Confirm destination exists, source removed
1324
1306
  - Check no leftover \`status:\` or \`## Resume Context\` in moved files
1325
1307
  - Update \`docs/priorities.mdx\` if it exists
1326
1308
  - Report: task title, cleanup stats (lines before/after), destination path
1327
-
1328
- ## Completion Suggestions
1329
-
1330
- When the agent observes that all plan steps for a task are marked COMPLETE and the user seems to be moving on, proactively suggest: "All steps for '{task}' are complete. Run \`/work complete\` to finalize it."
1331
1309
  `;
1332
1310
  }
1333
1311
  function claudeDocsCommandTemplate() {
@@ -1393,7 +1371,7 @@ Steps:
1393
1371
 
1394
1372
  ### \`create [description]\` -- Reference Doc Creation
1395
1373
 
1396
- Interview-driven creation for permanent documentation. Task docs go through \`/work create\`.
1374
+ Interview-driven creation for permanent documentation. Task docs go through \`/work\`.
1397
1375
 
1398
1376
  1. If no description given, ask: "What do you want to document?"
1399
1377
  2. Determine doc type (infer or ask):
@@ -1727,17 +1705,19 @@ Exactly three values for frontmatter \`status\`: \`planned\`, \`in-progress\`, \
1727
1705
  - IN PROGRESS -> COMPLETE (finishing a step)
1728
1706
  - Do NOT update on every action -- only on step transitions
1729
1707
 
1730
- ## Save Suggestions
1708
+ ## Auto-Save Behavior
1731
1709
 
1732
- Proactively suggest \`/work save\` when:
1710
+ The agent auto-saves progress (no user action needed) when:
1733
1711
  - The conversation context is getting heavy (many tool calls, large file reads)
1734
1712
  - The user appears to be wrapping up (thanks, goodbye, switching topics)
1735
1713
  - Significant progress has been made (2+ steps completed without saving)
1736
- - Before a \`/clear\` or context reset
1714
+ - Before a context reset
1715
+
1716
+ Auto-save updates the task doc's Progress and Resume Context sections silently, then briefly confirms.
1737
1717
 
1738
1718
  ## Completion Suggestions
1739
1719
 
1740
- When all plan steps are marked COMPLETE, suggest \`/work complete\` to finalize the task.
1720
+ When all plan steps are marked COMPLETE, **suggest** completing the task -- never auto-invoke. Ask: "All steps for '{task}' look done. Want me to finalize it?"
1741
1721
 
1742
1722
  ## Directory Conventions
1743
1723
 
@@ -1862,7 +1842,7 @@ const RECOVERY_TABLE = [
1862
1842
  test: r => /boundary hook/i.test(r) && /block|denied/i.test(r),
1863
1843
  advice: 'Command blocked by SDK boundary hook.',
1864
1844
  fix: 'Ask the user to run this command manually.',
1865
- why: 'The boundary hook blocks gh CLI, destructive git operations, and file writes outside the project.',
1845
+ why: 'The boundary hook blocks file modifications (Write, Edit, destructive Bash) outside the project boundary.',
1866
1846
  see: 'CLAUDE.md',
1867
1847
  },
1868
1848
  {