aiwcli 0.12.8 → 0.13.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.
- package/dist/commands/clean.d.ts +7 -0
- package/dist/commands/clean.js +17 -8
- package/dist/commands/clear.d.ts +85 -0
- package/dist/commands/clear.js +455 -347
- package/dist/commands/init/index.d.ts +15 -0
- package/dist/commands/init/index.js +79 -38
- package/dist/lib/gitignore-manager.js +12 -13
- package/dist/lib/settings-hierarchy.d.ts +13 -1
- package/dist/lib/settings-hierarchy.js +1 -1
- package/dist/lib/template-linter.d.ts +4 -0
- package/dist/lib/template-linter.js +1 -1
- package/dist/lib/tty-detection.d.ts +1 -0
- package/dist/lib/tty-detection.js +1 -0
- package/dist/templates/CLAUDE.md +1 -1
- package/dist/templates/_shared/.claude/settings.json +7 -7
- package/dist/templates/_shared/.claude/skills/handoff/SKILL.md +1 -1
- package/dist/templates/_shared/.claude/skills/handoff-resume/SKILL.md +1 -1
- package/dist/templates/_shared/.claude/skills/meta-plan/SKILL.md +43 -0
- package/dist/templates/_shared/.codex/workflows/handoff.md +1 -1
- package/dist/templates/_shared/.codex/workflows/meta-plan.md +347 -0
- package/dist/templates/_shared/.windsurf/workflows/handoff.md +1 -1
- package/dist/templates/_shared/.windsurf/workflows/meta-plan.md +347 -0
- package/dist/templates/_shared/hooks-ts/lint_after_edit.ts +59 -0
- package/dist/templates/_shared/hooks-ts/session_end.ts +11 -10
- package/dist/templates/_shared/hooks-ts/session_start.ts +15 -12
- package/dist/templates/_shared/hooks-ts/user_prompt_submit.ts +12 -12
- package/dist/templates/_shared/lib-ts/base/hook-utils.ts +26 -7
- package/dist/templates/_shared/lib-ts/base/inference.ts +16 -16
- package/dist/templates/_shared/lib-ts/base/lint-dispatch.ts +287 -0
- package/dist/templates/_shared/lib-ts/base/state-io.ts +4 -3
- package/dist/templates/_shared/lib-ts/base/subprocess-utils.ts +3 -3
- package/dist/templates/_shared/lib-ts/context/context-formatter.ts +16 -15
- package/dist/templates/_shared/lib-ts/context/context-selector.ts +16 -16
- package/dist/templates/_shared/lib-ts/context/context-store.ts +15 -14
- package/dist/templates/_shared/lib-ts/context/plan-manager.ts +2 -2
- package/dist/templates/_shared/scripts/resolve-run.ts +61 -0
- package/dist/templates/_shared/scripts/resolve_context.ts +1 -1
- package/dist/templates/_shared/scripts/status_line.ts +74 -65
- package/dist/templates/_shared/{handoff-system → skills/handoff-system}/CLAUDE.md +10 -10
- package/dist/templates/_shared/{handoff-system → skills/handoff-system}/lib/document-generator.ts +5 -4
- package/dist/templates/_shared/{handoff-system → skills/handoff-system}/lib/handoff-reader.ts +2 -1
- package/dist/templates/_shared/{handoff-system → skills/handoff-system}/scripts/resume_handoff.ts +6 -6
- package/dist/templates/_shared/{handoff-system → skills/handoff-system}/scripts/save_handoff.ts +16 -17
- package/dist/templates/_shared/{handoff-system → skills/handoff-system}/workflows/handoff-resume.md +2 -2
- package/dist/templates/_shared/{handoff-system → skills/handoff-system}/workflows/handoff.md +3 -3
- package/dist/templates/_shared/skills/meta-plan/CLAUDE.md +44 -0
- package/dist/templates/_shared/skills/meta-plan/workflows/meta-plan.md +347 -0
- package/dist/templates/cc-native/.claude/settings.json +84 -56
- package/dist/templates/cc-native/_cc-native/artifacts/lib/format.ts +8 -6
- package/dist/templates/cc-native/_cc-native/artifacts/lib/index.ts +11 -11
- package/dist/templates/cc-native/_cc-native/artifacts/lib/tracker.ts +7 -6
- package/dist/templates/cc-native/_cc-native/artifacts/lib/write.ts +17 -16
- package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.ts +9 -7
- package/dist/templates/cc-native/_cc-native/hooks/validate_task_prompt.ts +2 -2
- package/dist/templates/cc-native/_cc-native/lib-ts/cc-native-state.ts +15 -16
- package/dist/templates/cc-native/_cc-native/lib-ts/index.ts +19 -19
- package/dist/templates/cc-native/_cc-native/lib-ts/plan-discovery.ts +3 -3
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/embedding-indexer.ts +16 -12
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/hyde.ts +2 -3
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/index.ts +31 -31
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/logger.ts +7 -6
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/ollama-client.ts +9 -7
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/retrieval-pipeline.ts +17 -14
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-indexer.ts +41 -37
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-loader.ts +43 -33
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-searcher.ts +20 -20
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/types.ts +9 -8
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/vector-store.ts +4 -3
- package/dist/templates/cc-native/_cc-native/lib-ts/settings.ts +8 -9
- package/dist/templates/cc-native/_cc-native/lib-ts/state.ts +20 -19
- package/dist/templates/cc-native/_cc-native/lib-ts/types.ts +1 -1
- package/dist/templates/cc-native/_cc-native/plan-review/lib/agent-selection.ts +2 -3
- package/dist/templates/cc-native/_cc-native/plan-review/lib/graduation.ts +1 -1
- package/dist/templates/cc-native/_cc-native/plan-review/lib/orchestrator.ts +1 -1
- package/dist/templates/cc-native/_cc-native/plan-review/lib/output-builder.ts +12 -21
- package/dist/templates/cc-native/_cc-native/plan-review/lib/plan-questions.ts +3 -4
- package/dist/templates/cc-native/_cc-native/plan-review/lib/review-pipeline.ts +35 -39
- package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/agent.ts +2 -3
- package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/providers/codex-agent.ts +1 -1
- package/oclif.manifest.json +1 -1
- package/package.json +6 -5
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import * as fs from "node:fs";
|
|
11
11
|
import * as path from "node:path";
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
import { atomicWrite } from "../base/atomic-write.js";
|
|
14
14
|
import {
|
|
15
15
|
getContextDir,
|
|
@@ -20,7 +20,8 @@ import {
|
|
|
20
20
|
getArchiveIndexPath,
|
|
21
21
|
validateContextId,
|
|
22
22
|
} from "../base/constants.js";
|
|
23
|
-
import {
|
|
23
|
+
import { logInfo, logWarn, logError, setContextPath } from "../base/logger.js";
|
|
24
|
+
import { readStateJson, writeStateJson } from "../base/state-io.js";
|
|
24
25
|
import { nowIso, generateContextId } from "../base/utils.js";
|
|
25
26
|
import type { ContextState, IndexFile, IndexEntry, Mode } from "../types.js";
|
|
26
27
|
|
|
@@ -77,8 +78,8 @@ function loadIndex(projectRoot?: string): IndexFile {
|
|
|
77
78
|
try {
|
|
78
79
|
const raw = fs.readFileSync(indexPath, "utf-8");
|
|
79
80
|
return JSON.parse(raw) as IndexFile;
|
|
80
|
-
} catch (
|
|
81
|
-
logWarn("context_store", `Failed to read index, recreating: ${
|
|
81
|
+
} catch (error: any) {
|
|
82
|
+
logWarn("context_store", `Failed to read index, recreating: ${error}`);
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
85
|
return { version: INDEX_VERSION, updated_at: nowIso(), sessions: {}, contexts: {} };
|
|
@@ -145,8 +146,8 @@ function migrateContextJson(contextId: string, projectRoot?: string): ContextSta
|
|
|
145
146
|
last_session: null,
|
|
146
147
|
tasks: [],
|
|
147
148
|
};
|
|
148
|
-
} catch (
|
|
149
|
-
logWarn("context_store", `Failed to migrate context.json for '${contextId}': ${
|
|
149
|
+
} catch (error: any) {
|
|
150
|
+
logWarn("context_store", `Failed to migrate context.json for '${contextId}': ${error}`);
|
|
150
151
|
return null;
|
|
151
152
|
}
|
|
152
153
|
}
|
|
@@ -556,8 +557,8 @@ export function archiveContext(contextId: string, projectRoot?: string): Context
|
|
|
556
557
|
|
|
557
558
|
try {
|
|
558
559
|
fs.renameSync(sourceDir, archiveDest);
|
|
559
|
-
} catch (
|
|
560
|
-
logError("context_store", `Failed to move context to archive: ${
|
|
560
|
+
} catch (error: any) {
|
|
561
|
+
logError("context_store", `Failed to move context to archive: ${error}`);
|
|
561
562
|
return null;
|
|
562
563
|
}
|
|
563
564
|
|
|
@@ -647,8 +648,8 @@ function updateArchiveIndex(state: ContextState, projectRoot?: string): boolean
|
|
|
647
648
|
if (fs.existsSync(archiveIndexPath)) {
|
|
648
649
|
try {
|
|
649
650
|
archiveIndex = JSON.parse(fs.readFileSync(archiveIndexPath, "utf-8"));
|
|
650
|
-
} catch (
|
|
651
|
-
logWarn("context_store", `Failed to read archive index, recreating: ${
|
|
651
|
+
} catch (error_: any) {
|
|
652
|
+
logWarn("context_store", `Failed to read archive index, recreating: ${error_}`);
|
|
652
653
|
}
|
|
653
654
|
}
|
|
654
655
|
|
|
@@ -675,8 +676,8 @@ function restoreFromArchive(contextId: string, projectRoot?: string): ContextSta
|
|
|
675
676
|
|
|
676
677
|
try {
|
|
677
678
|
fs.renameSync(archiveDir, activeDir);
|
|
678
|
-
} catch (
|
|
679
|
-
logError("context_store", `Failed to restore context from archive: ${
|
|
679
|
+
} catch (error: any) {
|
|
680
|
+
logError("context_store", `Failed to restore context from archive: ${error}`);
|
|
680
681
|
return null;
|
|
681
682
|
}
|
|
682
683
|
|
|
@@ -705,8 +706,8 @@ function removeFromArchiveIndex(contextId: string, projectRoot?: string): boolea
|
|
|
705
706
|
}
|
|
706
707
|
}
|
|
707
708
|
return true;
|
|
708
|
-
} catch (
|
|
709
|
-
logWarn("context_store", `Failed to read archive index: ${
|
|
709
|
+
} catch (error: any) {
|
|
710
|
+
logWarn("context_store", `Failed to read archive index: ${error}`);
|
|
710
711
|
return false;
|
|
711
712
|
}
|
|
712
713
|
}
|
|
@@ -13,10 +13,9 @@ import * as fs from "node:fs";
|
|
|
13
13
|
import * as path from "node:path";
|
|
14
14
|
|
|
15
15
|
import { atomicWrite } from "../base/atomic-write.js";
|
|
16
|
-
import {
|
|
16
|
+
import { getContextPlansDir, sanitizeTitle } from "../base/constants.js";
|
|
17
17
|
import { logDebug, logInfo, logWarn, logError } from "../base/logger.js";
|
|
18
18
|
import { generateSlug } from "../base/utils.js";
|
|
19
|
-
import type { ContextState } from "../types.js";
|
|
20
19
|
|
|
21
20
|
// ---------------------------------------------------------------------------
|
|
22
21
|
// Plan archival
|
|
@@ -144,6 +143,7 @@ export function findLatestPlan(
|
|
|
144
143
|
// 1. Check state.json plan_path first
|
|
145
144
|
try {
|
|
146
145
|
// Dynamic import to avoid circular dependency at module level
|
|
146
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports, no-undef -- dynamic require to avoid circular dependency
|
|
147
147
|
const stateIo = require("../base/state-io.js");
|
|
148
148
|
const state = stateIo.readStateJson(contextId, projectRoot);
|
|
149
149
|
if (state?.plan_path && fs.existsSync(state.plan_path)) {
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* Cross-platform project root resolver for hook and status line commands.
|
|
4
|
+
*
|
|
5
|
+
* Finds the project root (via git or .aiwcli/ anchor walk-up), then spawns
|
|
6
|
+
* the target script with cwd set to the root. stdin/stdout/stderr pass through.
|
|
7
|
+
*
|
|
8
|
+
* Install: ~/.aiwcli/bin/resolve-run.ts (global, always findable via ~)
|
|
9
|
+
* Usage: bun ~/.aiwcli/bin/resolve-run.ts .aiwcli/_shared/scripts/status_line.ts
|
|
10
|
+
*
|
|
11
|
+
* Works on: bash, zsh, PowerShell, cmd (anywhere bun + ~ expansion works)
|
|
12
|
+
*/
|
|
13
|
+
import { execSync } from "node:child_process";
|
|
14
|
+
import * as fs from "node:fs";
|
|
15
|
+
import * as path from "node:path";
|
|
16
|
+
|
|
17
|
+
function findProjectRoot(): string {
|
|
18
|
+
// 1. git (works from any subdirectory of a repo)
|
|
19
|
+
try {
|
|
20
|
+
const root = execSync("git rev-parse --show-toplevel", {
|
|
21
|
+
encoding: "utf-8",
|
|
22
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
23
|
+
timeout: 2000,
|
|
24
|
+
}).trim();
|
|
25
|
+
if (root && fs.existsSync(path.join(root, ".aiwcli"))) return root;
|
|
26
|
+
} catch { /* not a git repo or git not available */ }
|
|
27
|
+
|
|
28
|
+
// 2. Walk up from cwd to find .aiwcli/ anchor
|
|
29
|
+
let dir = process.cwd();
|
|
30
|
+
while (true) {
|
|
31
|
+
if (fs.existsSync(path.join(dir, ".aiwcli"))) return dir;
|
|
32
|
+
const parent = path.dirname(dir);
|
|
33
|
+
if (parent === dir) break;
|
|
34
|
+
dir = parent;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return process.cwd(); // last resort
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const target = process.argv[2];
|
|
41
|
+
if (!target) {
|
|
42
|
+
process.stderr.write("resolve-run: missing script path argument\n");
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const root = findProjectRoot();
|
|
47
|
+
const fullPath = path.resolve(root, target);
|
|
48
|
+
|
|
49
|
+
if (!fs.existsSync(fullPath)) {
|
|
50
|
+
process.stderr.write(`resolve-run: script not found: ${fullPath}\n`);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const result = Bun.spawnSync(["bun", fullPath], {
|
|
55
|
+
stdin: "inherit",
|
|
56
|
+
stdout: "inherit",
|
|
57
|
+
stderr: "inherit",
|
|
58
|
+
cwd: root,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
process.exit(result.exitCode);
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
*
|
|
12
12
|
* Requires CLAUDE_SESSION_ID environment variable (set by Claude Code).
|
|
13
13
|
*/
|
|
14
|
-
import { getContextBySessionId } from "../lib-ts/context/context-store.js";
|
|
15
14
|
import { getProjectRoot } from "../lib-ts/base/constants.js";
|
|
16
15
|
import { eprint } from "../lib-ts/base/utils.js";
|
|
16
|
+
import { getContextBySessionId } from "../lib-ts/context/context-store.js";
|
|
17
17
|
|
|
18
18
|
const projectRoot = getProjectRoot(process.cwd());
|
|
19
19
|
const sessionId = process.env.CLAUDE_SESSION_ID;
|
|
@@ -22,7 +22,10 @@ import { findLatestPlan } from "../lib-ts/context/plan-manager.js";
|
|
|
22
22
|
// Path setup
|
|
23
23
|
// ---------------------------------------------------------------------------
|
|
24
24
|
const SCRIPT_DIR = path.dirname(new URL(import.meta.url).pathname);
|
|
25
|
-
|
|
25
|
+
// Resolve project root from script location (.aiwcli/_shared/scripts/) so paths
|
|
26
|
+
// work even when cwd has drifted via `cd` in a Bash tool call.
|
|
27
|
+
const PROJECT_ROOT = path.resolve(SCRIPT_DIR, "..", "..", "..");
|
|
28
|
+
const OUTPUT_DIR = path.join(PROJECT_ROOT, "_output");
|
|
26
29
|
const CACHE_DIR = path.join(OUTPUT_DIR, "cache");
|
|
27
30
|
const STATUSLINE_CACHE = path.join(CACHE_DIR, ".statusline-cache.json");
|
|
28
31
|
|
|
@@ -342,89 +345,97 @@ function getGitStatus(cwd: string): GitStatus | null {
|
|
|
342
345
|
return status;
|
|
343
346
|
}
|
|
344
347
|
|
|
345
|
-
function renderGit(mode: string, git: GitStatus, dirName: string): void {
|
|
346
|
-
const totalChanged = git.modified + git.staged;
|
|
347
|
-
const statusIcon = (totalChanged > 0 || git.untracked > 0) ? "*" : "\u2713";
|
|
348
|
+
function renderGit(mode: string, git: GitStatus | null, dirName: string): void {
|
|
349
|
+
const totalChanged = git ? git.modified + git.staged : 0;
|
|
350
|
+
const statusIcon = git && (totalChanged > 0 || git.untracked > 0) ? "*" : "\u2713";
|
|
348
351
|
|
|
349
352
|
switch (mode) {
|
|
350
353
|
case "micro": {
|
|
351
|
-
let line = `${GIT_PRIMARY}\u25C8${RESET} ${GIT_DIR}${dirName}${RESET}
|
|
352
|
-
if (git
|
|
353
|
-
line += ` ${
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
line +=
|
|
358
|
-
|
|
359
|
-
|
|
354
|
+
let line = `${GIT_PRIMARY}\u25C8${RESET} ${GIT_DIR}${dirName}${RESET}`;
|
|
355
|
+
if (git) {
|
|
356
|
+
line += ` ${GIT_VALUE}${git.branch}${RESET}`;
|
|
357
|
+
if (git.age_display) {
|
|
358
|
+
line += ` ${git.age_color}${git.age_display}${RESET}`;
|
|
359
|
+
}
|
|
360
|
+
line += " ";
|
|
361
|
+
if (statusIcon === "\u2713") {
|
|
362
|
+
line += `${GIT_CLEAN}${statusIcon}${RESET}`;
|
|
363
|
+
} else {
|
|
364
|
+
line += `${GIT_MODIFIED}${statusIcon}${totalChanged}${RESET}`;
|
|
365
|
+
}
|
|
360
366
|
}
|
|
361
367
|
console.log(line);
|
|
362
|
-
|
|
368
|
+
|
|
363
369
|
break;
|
|
364
370
|
}
|
|
365
371
|
case "mini": {
|
|
366
|
-
let line =
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
372
|
+
let line = `${GIT_PRIMARY}\u25C8${RESET} ${GIT_DIR}${dirName}${RESET}`;
|
|
373
|
+
if (git) {
|
|
374
|
+
line += ` ${SLATE_600}\u2502${RESET} ${GIT_VALUE}${git.branch}${RESET}`;
|
|
375
|
+
if (git.age_display) {
|
|
376
|
+
line += ` ${SLATE_600}\u2502${RESET} ${git.age_color}${git.age_display}${RESET}`;
|
|
377
|
+
}
|
|
378
|
+
line += ` ${SLATE_600}\u2502${RESET} `;
|
|
379
|
+
if (statusIcon === "\u2713") {
|
|
380
|
+
line += `${GIT_CLEAN}${statusIcon}${RESET}`;
|
|
381
|
+
} else {
|
|
382
|
+
line += `${GIT_MODIFIED}${statusIcon}${totalChanged}${RESET}`;
|
|
383
|
+
if (git.untracked > 0) {
|
|
384
|
+
line += ` ${GIT_ADDED}+${git.untracked}${RESET}`;
|
|
385
|
+
}
|
|
379
386
|
}
|
|
380
387
|
}
|
|
381
388
|
console.log(line);
|
|
382
|
-
|
|
389
|
+
|
|
383
390
|
break;
|
|
384
391
|
}
|
|
385
392
|
case "nano": {
|
|
386
|
-
let line = `${GIT_PRIMARY}\u25C8${RESET} ${GIT_DIR}${dirName}${RESET}
|
|
387
|
-
if (
|
|
388
|
-
line +=
|
|
389
|
-
|
|
390
|
-
|
|
393
|
+
let line = `${GIT_PRIMARY}\u25C8${RESET} ${GIT_DIR}${dirName}${RESET}`;
|
|
394
|
+
if (git) {
|
|
395
|
+
line += ` ${GIT_VALUE}${git.branch}${RESET} `;
|
|
396
|
+
if (statusIcon === "\u2713") {
|
|
397
|
+
line += `${GIT_CLEAN}\u2713${RESET}`;
|
|
398
|
+
} else {
|
|
399
|
+
line += `${GIT_MODIFIED}*${totalChanged}${RESET}`;
|
|
400
|
+
}
|
|
391
401
|
}
|
|
392
402
|
console.log(line);
|
|
393
|
-
|
|
403
|
+
|
|
394
404
|
break;
|
|
395
405
|
}
|
|
396
406
|
default: {
|
|
397
|
-
let line =
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
}
|
|
404
|
-
if (git.stash_count > 0) {
|
|
405
|
-
line += ` ${SLATE_600}\u2502${RESET} ${GIT_PRIMARY}Stash:${RESET} ${GIT_STASH}${git.stash_count}${RESET}`;
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
if (totalChanged > 0 || git.untracked > 0) {
|
|
409
|
-
line += ` ${SLATE_600}\u2502${RESET} `;
|
|
410
|
-
if (totalChanged > 0) {
|
|
411
|
-
line += `${GIT_PRIMARY}Mod:${RESET} ${GIT_MODIFIED}${totalChanged}${RESET}`;
|
|
407
|
+
let line = `${GIT_PRIMARY}\u25C8${RESET} ${GIT_PRIMARY}PWD:${RESET} ${GIT_DIR}${dirName}${RESET}`;
|
|
408
|
+
if (git) {
|
|
409
|
+
line += ` ${SLATE_600}\u2502${RESET} ` +
|
|
410
|
+
`${GIT_PRIMARY}Branch:${RESET} ${GIT_VALUE}${git.branch}${RESET}`;
|
|
411
|
+
if (git.age_display) {
|
|
412
|
+
line += ` ${SLATE_600}\u2502${RESET} ${GIT_PRIMARY}Age:${RESET} ${git.age_color}${git.age_display}${RESET}`;
|
|
412
413
|
}
|
|
413
|
-
if (git.
|
|
414
|
-
|
|
415
|
-
line += `${GIT_PRIMARY}New:${RESET} ${GIT_ADDED}${git.untracked}${RESET}`;
|
|
414
|
+
if (git.stash_count > 0) {
|
|
415
|
+
line += ` ${SLATE_600}\u2502${RESET} ${GIT_PRIMARY}Stash:${RESET} ${GIT_STASH}${git.stash_count}${RESET}`;
|
|
416
416
|
}
|
|
417
|
-
} else {
|
|
418
|
-
line += ` ${SLATE_600}\u2502${RESET} ${GIT_CLEAN}\u2713 clean${RESET}`;
|
|
419
|
-
}
|
|
420
417
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
418
|
+
if (totalChanged > 0 || git.untracked > 0) {
|
|
419
|
+
line += ` ${SLATE_600}\u2502${RESET} `;
|
|
420
|
+
if (totalChanged > 0) {
|
|
421
|
+
line += `${GIT_PRIMARY}Mod:${RESET} ${GIT_MODIFIED}${totalChanged}${RESET}`;
|
|
422
|
+
}
|
|
423
|
+
if (git.untracked > 0) {
|
|
424
|
+
if (totalChanged > 0) line += " ";
|
|
425
|
+
line += `${GIT_PRIMARY}New:${RESET} ${GIT_ADDED}${git.untracked}${RESET}`;
|
|
426
|
+
}
|
|
427
|
+
} else {
|
|
428
|
+
line += ` ${SLATE_600}\u2502${RESET} ${GIT_CLEAN}\u2713 clean${RESET}`;
|
|
425
429
|
}
|
|
426
|
-
|
|
427
|
-
|
|
430
|
+
|
|
431
|
+
if (git.ahead > 0 || git.behind > 0) {
|
|
432
|
+
line += ` ${SLATE_600}\u2502${RESET} ${GIT_PRIMARY}Sync:${RESET} `;
|
|
433
|
+
if (git.ahead > 0) {
|
|
434
|
+
line += `${GIT_CLEAN}\u2191${git.ahead}${RESET}`;
|
|
435
|
+
}
|
|
436
|
+
if (git.behind > 0) {
|
|
437
|
+
line += `${GIT_STASH}\u2193${git.behind}${RESET}`;
|
|
438
|
+
}
|
|
428
439
|
}
|
|
429
440
|
}
|
|
430
441
|
console.log(line);
|
|
@@ -684,11 +695,9 @@ function main(): void {
|
|
|
684
695
|
// Render context section
|
|
685
696
|
renderContext(mode, contextPct, contextK, maxK, timeDisplay, modelName);
|
|
686
697
|
|
|
687
|
-
// Render git section
|
|
698
|
+
// Render PWD + git section (PWD always shown, git stats only when in a repo)
|
|
688
699
|
const git = getGitStatus(currentDir);
|
|
689
|
-
|
|
690
|
-
renderGit(mode, git, dirName);
|
|
691
|
-
}
|
|
700
|
+
renderGit(mode, git, dirName);
|
|
692
701
|
|
|
693
702
|
// Render context manager line (line 3) with separator
|
|
694
703
|
console.log(SEPARATOR);
|
|
@@ -173,7 +173,7 @@ If `plan_hash` differs from `plan_hash_consumed`, new plan detected:
|
|
|
173
173
|
|
|
174
174
|
**Usage:**
|
|
175
175
|
```bash
|
|
176
|
-
bun .aiwcli/_shared/handoff-system/scripts/save_handoff.ts [--context-id ID] [--session-id SID] < handoff.md
|
|
176
|
+
bun .aiwcli/_shared/skills/handoff-system/scripts/save_handoff.ts [--context-id ID] [--session-id SID] < handoff.md
|
|
177
177
|
```
|
|
178
178
|
|
|
179
179
|
**Stdin format:**
|
|
@@ -209,13 +209,13 @@ If timestamp folder exists, appends `-2`, `-3`, etc.
|
|
|
209
209
|
**Usage:**
|
|
210
210
|
```bash
|
|
211
211
|
# Auto-discover from current session
|
|
212
|
-
bun .aiwcli/_shared/handoff-system/scripts/resume_handoff.ts
|
|
212
|
+
bun .aiwcli/_shared/skills/handoff-system/scripts/resume_handoff.ts
|
|
213
213
|
|
|
214
214
|
# Explicit handoff path
|
|
215
|
-
bun .aiwcli/_shared/handoff-system/scripts/resume_handoff.ts path/to/handoff/index.md
|
|
215
|
+
bun .aiwcli/_shared/skills/handoff-system/scripts/resume_handoff.ts path/to/handoff/index.md
|
|
216
216
|
|
|
217
217
|
# Explicit context
|
|
218
|
-
bun .aiwcli/_shared/handoff-system/scripts/resume_handoff.ts --context context-id
|
|
218
|
+
bun .aiwcli/_shared/skills/handoff-system/scripts/resume_handoff.ts --context context-id
|
|
219
219
|
```
|
|
220
220
|
|
|
221
221
|
**Output format (to stdout):**
|
|
@@ -257,7 +257,7 @@ Uses `CLAUDE_SESSION_ID` env var → lookup context → find latest handoff in `
|
|
|
257
257
|
|
|
258
258
|
### handoff-reader.ts
|
|
259
259
|
|
|
260
|
-
**Location:** `_shared/handoff-system/lib/handoff-reader.ts`
|
|
260
|
+
**Location:** `_shared/skills/handoff-system/lib/handoff-reader.ts`
|
|
261
261
|
|
|
262
262
|
**Exports:**
|
|
263
263
|
|
|
@@ -292,7 +292,7 @@ const SECTION_FILES = {
|
|
|
292
292
|
|
|
293
293
|
### document-generator.ts
|
|
294
294
|
|
|
295
|
-
**Location:** `_shared/handoff-system/lib/document-generator.ts`
|
|
295
|
+
**Location:** `_shared/skills/handoff-system/lib/document-generator.ts`
|
|
296
296
|
|
|
297
297
|
**Exports:**
|
|
298
298
|
|
|
@@ -316,7 +316,7 @@ function buildDeadEndsSection(deadEnds: DeadEnd[]): string
|
|
|
316
316
|
**Thin pointer pattern:**
|
|
317
317
|
|
|
318
318
|
`.claude/skills/handoff/SKILL.md` (user-facing, discoverable via `/`, `user-invocable: true`)
|
|
319
|
-
→ References `.aiwcli/_shared/handoff-system/workflows/handoff.md` (detailed procedural steps)
|
|
319
|
+
→ References `.aiwcli/_shared/skills/handoff-system/workflows/handoff.md` (detailed procedural steps)
|
|
320
320
|
|
|
321
321
|
**Benefits:**
|
|
322
322
|
- Skill files stay concise (easy to scan in `/` menu)
|
|
@@ -325,7 +325,7 @@ function buildDeadEndsSection(deadEnds: DeadEnd[]): string
|
|
|
325
325
|
|
|
326
326
|
**Example reference format:**
|
|
327
327
|
```markdown
|
|
328
|
-
See `.aiwcli/_shared/handoff-system/workflows/handoff.md` for complete process documentation.
|
|
328
|
+
See `.aiwcli/_shared/skills/handoff-system/workflows/handoff.md` for complete process documentation.
|
|
329
329
|
```
|
|
330
330
|
|
|
331
331
|
## Testing
|
|
@@ -406,7 +406,7 @@ Expected: No import errors, clean execution.
|
|
|
406
406
|
## Gotchas
|
|
407
407
|
|
|
408
408
|
**Template sync is mandatory:**
|
|
409
|
-
Both `.aiwcli/_shared/handoff-system/` (working copy) and `packages/cli/src/templates/_shared/handoff-system/` (template source) must stay in sync per CLAUDE.md template sync rules.
|
|
409
|
+
Both `.aiwcli/_shared/skills/handoff-system/` (working copy) and `packages/cli/src/templates/_shared/skills/handoff-system/` (template source) must stay in sync per CLAUDE.md template sync rules.
|
|
410
410
|
|
|
411
411
|
**Import paths after move:**
|
|
412
412
|
- From `scripts/resume_handoff.ts` → `lib/handoff-reader.ts`: `../lib/handoff-reader.js`
|
|
@@ -418,7 +418,7 @@ Both `.aiwcli/_shared/handoff-system/` (working copy) and `packages/cli/src/temp
|
|
|
418
418
|
- No direct handoff-reader dependency in hooks
|
|
419
419
|
|
|
420
420
|
**Command file script paths are absolute:**
|
|
421
|
-
- Reference from project root: `.aiwcli/_shared/handoff-system/scripts/save_handoff.ts`
|
|
421
|
+
- Reference from project root: `.aiwcli/_shared/skills/handoff-system/scripts/save_handoff.ts`
|
|
422
422
|
- NOT relative to command file location
|
|
423
423
|
|
|
424
424
|
**Section markers must be HTML comments:**
|
package/dist/templates/_shared/{handoff-system → skills/handoff-system}/lib/document-generator.ts
RENAMED
|
@@ -6,17 +6,18 @@
|
|
|
6
6
|
* work to a new session (typically due to context window limits).
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
import * as crypto from "node:crypto";
|
|
9
10
|
import * as fs from "node:fs";
|
|
10
11
|
import * as path from "node:path";
|
|
11
|
-
|
|
12
|
-
import { getContextHandoffsDir, getContextDir } from "../base/constants.js";
|
|
12
|
+
|
|
13
13
|
import { atomicWrite } from "../base/atomic-write.js";
|
|
14
|
+
import { getContextHandoffsDir, getContextDir } from "../base/constants.js";
|
|
14
15
|
import { logInfo, logError } from "../base/logger.js";
|
|
15
16
|
import { nowIso } from "../base/utils.js";
|
|
16
|
-
import { getContext
|
|
17
|
+
import { getContext } from "../context/context-store.js";
|
|
17
18
|
import { getTasks } from "../context/task-tracker.js";
|
|
18
19
|
import { renderTaskList, formatContinuationHeader, formatReason } from "../templates/formatters.js";
|
|
19
|
-
import type { HandoffDocument
|
|
20
|
+
import type { HandoffDocument } from "../types.js";
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
23
|
* Generate and save a handoff document for a context.
|
package/dist/templates/_shared/{handoff-system → skills/handoff-system}/lib/handoff-reader.ts
RENAMED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import * as fs from "node:fs";
|
|
10
10
|
import * as path from "node:path";
|
|
11
|
+
|
|
11
12
|
import { getContextHandoffsDir } from "../../lib-ts/base/constants.js";
|
|
12
13
|
import { getContext } from "../../lib-ts/context/context-store.js";
|
|
13
14
|
import type { HandoffSections } from "../../lib-ts/types.js";
|
|
@@ -29,7 +30,7 @@ export function findLatestHandoff(contextId: string, projectRoot?: string): stri
|
|
|
29
30
|
.sort();
|
|
30
31
|
|
|
31
32
|
if (entries.length === 0) return null;
|
|
32
|
-
return path.join(handoffsDir, entries
|
|
33
|
+
return path.join(handoffsDir, entries.at(-1)!);
|
|
33
34
|
} catch {
|
|
34
35
|
return null;
|
|
35
36
|
}
|
package/dist/templates/_shared/{handoff-system → skills/handoff-system}/scripts/resume_handoff.ts
RENAMED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* a structured briefing to stdout.
|
|
5
5
|
*
|
|
6
6
|
* Usage:
|
|
7
|
-
* bun .aiwcli/_shared/handoff-system/scripts/resume_handoff.ts <handoff_folder_or_index>
|
|
8
|
-
* bun .aiwcli/_shared/handoff-system/scripts/resume_handoff.ts --context <context_id>
|
|
7
|
+
* bun .aiwcli/_shared/skills/handoff-system/scripts/resume_handoff.ts <handoff_folder_or_index>
|
|
8
|
+
* bun .aiwcli/_shared/skills/handoff-system/scripts/resume_handoff.ts --context <context_id>
|
|
9
9
|
*
|
|
10
10
|
* If no args, auto-discovers the active context and finds the latest handoff.
|
|
11
11
|
*
|
|
@@ -15,16 +15,16 @@
|
|
|
15
15
|
import * as fs from "node:fs";
|
|
16
16
|
import * as path from "node:path";
|
|
17
17
|
|
|
18
|
+
import { getProjectRoot } from "../../lib-ts/base/constants.js";
|
|
19
|
+
import { getGitStatusShort } from "../../lib-ts/base/git-state.js";
|
|
20
|
+
import { eprint } from "../../lib-ts/base/utils.js";
|
|
21
|
+
import { getContextBySessionId } from "../../lib-ts/context/context-store.js";
|
|
18
22
|
import {
|
|
19
23
|
findLatestHandoff,
|
|
20
24
|
readHandoffSections,
|
|
21
25
|
getHandoffTimestamp,
|
|
22
26
|
getHandoffPlanReference,
|
|
23
27
|
} from "../lib/handoff-reader.js";
|
|
24
|
-
import { getProjectRoot } from "../../lib-ts/base/constants.js";
|
|
25
|
-
import { getContextBySessionId } from "../../lib-ts/context/context-store.js";
|
|
26
|
-
import { getGitStatusShort } from "../../lib-ts/base/git-state.js";
|
|
27
|
-
import { eprint } from "../../lib-ts/base/utils.js";
|
|
28
28
|
|
|
29
29
|
// ---------------------------------------------------------------------------
|
|
30
30
|
// Helpers
|
package/dist/templates/_shared/{handoff-system → skills/handoff-system}/scripts/save_handoff.ts
RENAMED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
* Save a handoff document with folder-based sharding.
|
|
4
4
|
*
|
|
5
5
|
* Usage:
|
|
6
|
-
* bun .aiwcli/_shared/handoff-system/scripts/save_handoff.ts <<'EOF'
|
|
6
|
+
* bun .aiwcli/_shared/skills/handoff-system/scripts/save_handoff.ts <<'EOF'
|
|
7
7
|
* # Your handoff markdown content here (with <!-- SECTION: name --> markers)
|
|
8
8
|
* EOF
|
|
9
9
|
*
|
|
10
10
|
* Or with a file:
|
|
11
|
-
* bun .aiwcli/_shared/handoff-system/scripts/save_handoff.ts < handoff.md
|
|
11
|
+
* bun .aiwcli/_shared/skills/handoff-system/scripts/save_handoff.ts < handoff.md
|
|
12
12
|
*
|
|
13
13
|
* This script:
|
|
14
14
|
* 1. Auto-resolves the active context ID
|
|
@@ -23,12 +23,12 @@
|
|
|
23
23
|
import * as fs from "node:fs";
|
|
24
24
|
import * as path from "node:path";
|
|
25
25
|
|
|
26
|
-
import { getContext, saveState, getContextBySessionId, getAllContexts } from "../../lib-ts/context/context-store.js";
|
|
27
|
-
import { getHandoffFolderPath, getProjectRoot } from "../../lib-ts/base/constants.js";
|
|
28
26
|
import { atomicWrite } from "../../lib-ts/base/atomic-write.js";
|
|
29
|
-
import {
|
|
27
|
+
import { getHandoffFolderPath, getProjectRoot } from "../../lib-ts/base/constants.js";
|
|
30
28
|
import { getGitStatusShort } from "../../lib-ts/base/git-state.js";
|
|
29
|
+
import { logInfo, logWarn, logError } from "../../lib-ts/base/logger.js";
|
|
31
30
|
import { eprint } from "../../lib-ts/base/utils.js";
|
|
31
|
+
import { getContext, saveState, getContextBySessionId, getAllContexts } from "../../lib-ts/context/context-store.js";
|
|
32
32
|
|
|
33
33
|
// ---------------------------------------------------------------------------
|
|
34
34
|
// Parsing helpers
|
|
@@ -333,8 +333,8 @@ function main(): void {
|
|
|
333
333
|
} else {
|
|
334
334
|
logWarn("save_handoff", `Failed to copy plan to handoff: ${error}`);
|
|
335
335
|
}
|
|
336
|
-
} catch (
|
|
337
|
-
logWarn("save_handoff", `Plan update failed (non-critical): ${
|
|
336
|
+
} catch (error) {
|
|
337
|
+
logWarn("save_handoff", `Plan update failed (non-critical): ${error}`);
|
|
338
338
|
}
|
|
339
339
|
} else if (planPath) {
|
|
340
340
|
// Fallback: copy unchanged plan if Claude didn't provide an update
|
|
@@ -346,8 +346,8 @@ function main(): void {
|
|
|
346
346
|
} else {
|
|
347
347
|
logWarn("save_handoff", `Failed to copy plan: ${error}`);
|
|
348
348
|
}
|
|
349
|
-
} catch (
|
|
350
|
-
logWarn("save_handoff", `Failed to read plan: ${
|
|
349
|
+
} catch (error) {
|
|
350
|
+
logWarn("save_handoff", `Failed to read plan: ${error}`);
|
|
351
351
|
}
|
|
352
352
|
}
|
|
353
353
|
|
|
@@ -384,13 +384,12 @@ function main(): void {
|
|
|
384
384
|
// Append mode
|
|
385
385
|
if (!fileContents[filename]) fileContents[filename] = [];
|
|
386
386
|
fileContents[filename]!.push(sectionContent);
|
|
387
|
+
} else if (!fileContents[filename]) {
|
|
388
|
+
// Write mode with title — new file
|
|
389
|
+
fileContents[filename] = [`# ${title}`, "", sectionContent];
|
|
387
390
|
} else {
|
|
388
|
-
// Write mode with title
|
|
389
|
-
|
|
390
|
-
fileContents[filename] = [`# ${title}`, "", sectionContent];
|
|
391
|
-
} else {
|
|
392
|
-
fileContents[filename] = [`# ${title}`, "", ...fileContents[filename]!, "", sectionContent];
|
|
393
|
-
}
|
|
391
|
+
// Write mode with title — prepend to existing
|
|
392
|
+
fileContents[filename] = [`# ${title}`, "", ...fileContents[filename]!, "", sectionContent];
|
|
394
393
|
}
|
|
395
394
|
}
|
|
396
395
|
|
|
@@ -449,8 +448,8 @@ function main(): void {
|
|
|
449
448
|
} else {
|
|
450
449
|
logWarn("save_handoff", `Could not load context state for ${contextId}`);
|
|
451
450
|
}
|
|
452
|
-
} catch (
|
|
453
|
-
logWarn("save_handoff", `Handoff saved but auto-resume won't work: ${
|
|
451
|
+
} catch (error) {
|
|
452
|
+
logWarn("save_handoff", `Handoff saved but auto-resume won't work: ${error}`);
|
|
454
453
|
}
|
|
455
454
|
|
|
456
455
|
// Output success message
|
package/dist/templates/_shared/{handoff-system → skills/handoff-system}/workflows/handoff-resume.md
RENAMED
|
@@ -16,13 +16,13 @@ Run the resume script to collect and format all handoff sections:
|
|
|
16
16
|
|
|
17
17
|
**If `$ARGUMENTS` is provided:**
|
|
18
18
|
```bash
|
|
19
|
-
bun .aiwcli/_shared/handoff-system/scripts/resume_handoff.ts "$ARGUMENTS"
|
|
19
|
+
bun .aiwcli/_shared/skills/handoff-system/scripts/resume_handoff.ts "$ARGUMENTS"
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
**If `$ARGUMENTS` is empty:**
|
|
23
23
|
The script auto-discovers the active context ID programmatically — no manual lookup needed:
|
|
24
24
|
```bash
|
|
25
|
-
bun .aiwcli/_shared/handoff-system/scripts/resume_handoff.ts
|
|
25
|
+
bun .aiwcli/_shared/skills/handoff-system/scripts/resume_handoff.ts
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
Present the script's output to the conversation. The output is already structured in priority order (dead ends first, then pending items, decisions, git delta, completed work, context notes).
|
package/dist/templates/_shared/{handoff-system → skills/handoff-system}/workflows/handoff.md
RENAMED
|
@@ -153,7 +153,7 @@ The closing `EOF` delimiter **MUST** be at column 0 (no leading spaces or tabs).
|
|
|
153
153
|
|
|
154
154
|
**Correct Example:**
|
|
155
155
|
```bash
|
|
156
|
-
bun .aiwcli/_shared/handoff-system/scripts/save_handoff.ts <<'EOF'
|
|
156
|
+
bun .aiwcli/_shared/skills/handoff-system/scripts/save_handoff.ts <<'EOF'
|
|
157
157
|
content here
|
|
158
158
|
EOF
|
|
159
159
|
```
|
|
@@ -161,7 +161,7 @@ EOF
|
|
|
161
161
|
|
|
162
162
|
**Wrong Example (will fail):**
|
|
163
163
|
```bash
|
|
164
|
-
bun .aiwcli/_shared/handoff-system/scripts/save_handoff.ts <<'EOF'
|
|
164
|
+
bun .aiwcli/_shared/skills/handoff-system/scripts/save_handoff.ts <<'EOF'
|
|
165
165
|
content here
|
|
166
166
|
EOF
|
|
167
167
|
```
|
|
@@ -172,7 +172,7 @@ content here
|
|
|
172
172
|
Instead of writing the file directly, pipe your handoff content to the save script:
|
|
173
173
|
|
|
174
174
|
```bash
|
|
175
|
-
bun .aiwcli/_shared/handoff-system/scripts/save_handoff.ts <<'EOF'
|
|
175
|
+
bun .aiwcli/_shared/skills/handoff-system/scripts/save_handoff.ts <<'EOF'
|
|
176
176
|
{Your complete handoff markdown content from Step 3}
|
|
177
177
|
EOF
|
|
178
178
|
```
|