@titan-design/active-work 0.5.0 → 0.7.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/aw.js +1 -1
- package/dist/{chunk-RLSQSE7I.js → chunk-KAR6NOS2.js} +306 -50
- package/dist/chunk-KAR6NOS2.js.map +1 -0
- package/dist/cli.js +717 -637
- package/dist/cli.js.map +1 -1
- package/docs/cli-reference.md +25 -0
- package/package.json +6 -5
- package/dist/chunk-RLSQSE7I.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
NotFoundError,
|
|
14
14
|
NoteFrontmatterSchema,
|
|
15
15
|
NoteKindSchema,
|
|
16
|
+
SCHEMA_VERSION,
|
|
16
17
|
SessionFrontmatterSchema,
|
|
17
18
|
SessionIdSchema,
|
|
18
19
|
SessionResolveSchema,
|
|
@@ -21,11 +22,13 @@ import {
|
|
|
21
22
|
TaskSeqSchema,
|
|
22
23
|
UsageError,
|
|
23
24
|
ValidationError,
|
|
25
|
+
WORKSPACE_SPAN_SOURCE_BASE,
|
|
24
26
|
WorktreeEntrySchema,
|
|
25
27
|
assembleBootstrap,
|
|
26
28
|
atomicWrite,
|
|
27
29
|
coerceDates,
|
|
28
30
|
color,
|
|
31
|
+
defaultGraphPath,
|
|
29
32
|
defineCommand,
|
|
30
33
|
deriveOpenLoops,
|
|
31
34
|
deriveOpenLoopsFrom,
|
|
@@ -48,6 +51,8 @@ import {
|
|
|
48
51
|
loadNotesFromDir,
|
|
49
52
|
loadSessionsFromDir,
|
|
50
53
|
nowIso,
|
|
54
|
+
openGraph,
|
|
55
|
+
openGraphReadOnly,
|
|
51
56
|
open_default,
|
|
52
57
|
probeHealth,
|
|
53
58
|
readArtifactHashes,
|
|
@@ -76,7 +81,7 @@ import {
|
|
|
76
81
|
writeFrontmatter,
|
|
77
82
|
writeNoteFile,
|
|
78
83
|
writeYaml
|
|
79
|
-
} from "./chunk-
|
|
84
|
+
} from "./chunk-KAR6NOS2.js";
|
|
80
85
|
|
|
81
86
|
// src/cli.ts
|
|
82
87
|
import { Command, CommanderError } from "commander";
|
|
@@ -3849,29 +3854,249 @@ var context_graph_default = defineCommand({
|
|
|
3849
3854
|
}
|
|
3850
3855
|
});
|
|
3851
3856
|
|
|
3852
|
-
// src/commands/
|
|
3857
|
+
// src/commands/search.ts
|
|
3853
3858
|
import { z as z33 } from "zod";
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
}
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3859
|
+
|
|
3860
|
+
// src/search/index.ts
|
|
3861
|
+
import { createRetrievalEngine, ftsRetriever } from "@titan-design/retrieval";
|
|
3862
|
+
|
|
3863
|
+
// src/search/classes.ts
|
|
3864
|
+
var TRANSCRIPT_FIELDS = ["prompt", "assistant_response", "tool_input", "tool_result"];
|
|
3865
|
+
var SEARCH_CLASSES = [
|
|
3866
|
+
{ name: "notes", scope: { ownerPrefix: "note:" }, weight: 1.3, share: 0.5 },
|
|
3867
|
+
// Briefs are the most distilled statement of what an initiative is, and there
|
|
3868
|
+
// are only 56 spans of them. The design's table predates the indexer and
|
|
3869
|
+
// omits the class; including it costs nothing and makes `brief.md` findable.
|
|
3870
|
+
{ name: "initiatives", scope: { ownerPrefix: "initiative:" }, weight: 1.15, share: 0.2 },
|
|
3871
|
+
{ name: "sources", scope: { ownerPrefix: "source:" }, weight: 1.1, share: 0.3 },
|
|
3872
|
+
{ name: "tasks", scope: { ownerPrefix: "task:" }, weight: 1, share: 0.3 },
|
|
3873
|
+
// Narrative restatements of the notes, written by the session that wrote
|
|
3874
|
+
// them: the workspace's own duplicate content, so low on both counts.
|
|
3875
|
+
{
|
|
3876
|
+
name: "sessions",
|
|
3877
|
+
scope: { ownerPrefix: "session:", fields: ["body"] },
|
|
3878
|
+
weight: 0.6,
|
|
3879
|
+
share: 0.2
|
|
3880
|
+
},
|
|
3881
|
+
{
|
|
3882
|
+
name: "transcripts",
|
|
3883
|
+
scope: { ownerPrefix: "session:", fields: TRANSCRIPT_FIELDS },
|
|
3884
|
+
weight: 0.45,
|
|
3885
|
+
share: 0.2
|
|
3886
|
+
}
|
|
3887
|
+
];
|
|
3888
|
+
function capFor(cls, limit) {
|
|
3889
|
+
return Math.max(1, Math.ceil(limit * cls.share));
|
|
3890
|
+
}
|
|
3891
|
+
function classOf(ref, field) {
|
|
3892
|
+
const prefix = ref.slice(0, ref.indexOf(":"));
|
|
3893
|
+
if (prefix !== "session") return `${prefix}s`;
|
|
3894
|
+
return field !== void 0 && TRANSCRIPT_FIELDS.includes(field) ? "transcripts" : "sessions";
|
|
3895
|
+
}
|
|
3896
|
+
|
|
3897
|
+
// src/search/resolve.ts
|
|
3898
|
+
import path35 from "path";
|
|
3899
|
+
import { readLocatorText } from "@titan-design/locator";
|
|
3900
|
+
|
|
3901
|
+
// src/workspace-index/refs.ts
|
|
3902
|
+
import path34 from "path";
|
|
3903
|
+
import { refKind } from "@titan-design/store-sqlite";
|
|
3904
|
+
var initiativeRef = refKind("initiative");
|
|
3905
|
+
var noteRef = refKind("note");
|
|
3906
|
+
var taskRef = refKind("task");
|
|
3907
|
+
var sessionRef = refKind("session");
|
|
3908
|
+
var sourceRef = refKind("source");
|
|
3909
|
+
function toRelative(activeRoot, absolutePath) {
|
|
3910
|
+
return path34.relative(activeRoot, absolutePath).split(path34.sep).join("/");
|
|
3911
|
+
}
|
|
3912
|
+
function toAbsolute(activeRoot, relativePath) {
|
|
3913
|
+
return path34.join(activeRoot, ...relativePath.split("/"));
|
|
3914
|
+
}
|
|
3915
|
+
|
|
3916
|
+
// src/search/resolve.ts
|
|
3917
|
+
var ROW_SOURCES = [
|
|
3918
|
+
{ table: "note", refColumn: "note_ref", title: "title" },
|
|
3919
|
+
{ table: "workspace_task", refColumn: "task_ref", title: "title" },
|
|
3920
|
+
{ table: "source", refColumn: "source_ref", title: "title" },
|
|
3921
|
+
{ table: "initiative", refColumn: "initiative_ref", title: "title" },
|
|
3922
|
+
{ table: "session_record", refColumn: "session_ref", title: "session_id" }
|
|
3923
|
+
];
|
|
3924
|
+
function rowFor(graph, ref) {
|
|
3925
|
+
for (const { table, refColumn, title } of ROW_SOURCES) {
|
|
3926
|
+
const row = graph.db.prepare(
|
|
3927
|
+
`SELECT path, "${title}" AS title, ${table === "initiative" ? "slug" : "initiative"} AS initiative
|
|
3928
|
+
FROM "${table}" WHERE "${refColumn}" = ? LIMIT 1`
|
|
3929
|
+
).get(ref);
|
|
3930
|
+
if (row) return row;
|
|
3931
|
+
}
|
|
3932
|
+
return null;
|
|
3933
|
+
}
|
|
3934
|
+
function fileForSource(graph, sourceId, activeRoot) {
|
|
3935
|
+
if (sourceId >= WORKSPACE_SPAN_SOURCE_BASE) {
|
|
3936
|
+
const row2 = graph.db.prepare("SELECT source_key FROM workspace_file WHERE source_id = ?").get(sourceId - WORKSPACE_SPAN_SOURCE_BASE);
|
|
3937
|
+
return row2 ? toAbsolute(activeRoot, row2.source_key) : null;
|
|
3938
|
+
}
|
|
3939
|
+
const row = graph.db.prepare("SELECT source_key FROM transcript WHERE source_id = ?").get(sourceId);
|
|
3940
|
+
if (!row) return null;
|
|
3941
|
+
return row.source_key.startsWith("~") ? path35.join(process.env.HOME ?? "", row.source_key.slice(1)) : row.source_key;
|
|
3942
|
+
}
|
|
3943
|
+
function oneLine(text, width) {
|
|
3944
|
+
const flat = text.replace(/\s+/g, " ").trim();
|
|
3945
|
+
return flat.length <= width ? flat : `${flat.slice(0, width - 1)}\u2026`;
|
|
3946
|
+
}
|
|
3947
|
+
async function excerptFor(graph, payload, activeRoot, width) {
|
|
3948
|
+
if (!payload) return null;
|
|
3949
|
+
const file = fileForSource(graph, payload.sourceId, activeRoot);
|
|
3950
|
+
if (file === null) return null;
|
|
3951
|
+
try {
|
|
3952
|
+
const locator = [0, payload.byteOffset, payload.byteLength];
|
|
3953
|
+
return oneLine(await readLocatorText(file, locator), width);
|
|
3954
|
+
} catch {
|
|
3955
|
+
return null;
|
|
3956
|
+
}
|
|
3957
|
+
}
|
|
3958
|
+
function spanPayload(result) {
|
|
3959
|
+
const first = Object.values(result.payloads)[0];
|
|
3960
|
+
return first;
|
|
3961
|
+
}
|
|
3962
|
+
async function resolveHits(graph, results, activeRoot, excerptWidth) {
|
|
3963
|
+
return Promise.all(
|
|
3964
|
+
results.map(async (result) => {
|
|
3965
|
+
const payload = spanPayload(result);
|
|
3966
|
+
const row = rowFor(graph, result.id);
|
|
3967
|
+
return {
|
|
3968
|
+
ref: result.id,
|
|
3969
|
+
class: classOf(result.id, payload?.field),
|
|
3970
|
+
initiative: row?.initiative ?? null,
|
|
3971
|
+
title: row?.title ?? null,
|
|
3972
|
+
path: row?.path ?? null,
|
|
3973
|
+
excerpt: await excerptFor(graph, payload, activeRoot, excerptWidth),
|
|
3974
|
+
score: result.score,
|
|
3975
|
+
sources: result.sources
|
|
3976
|
+
};
|
|
3977
|
+
})
|
|
3978
|
+
);
|
|
3979
|
+
}
|
|
3980
|
+
|
|
3981
|
+
// src/search/index.ts
|
|
3982
|
+
var AFFINITY_BOOST = 7e-3;
|
|
3983
|
+
async function searchWorkspace(query, options = {}) {
|
|
3984
|
+
const activeRoot = options.activeRoot ?? getActiveRoot();
|
|
3985
|
+
const graph = options.graph ?? openGraph(options.dbPath ?? defaultGraphPath());
|
|
3986
|
+
const owned = options.graph === void 0;
|
|
3987
|
+
const limit = options.limit ?? 10;
|
|
3988
|
+
try {
|
|
3989
|
+
const engine = createRetrievalEngine({
|
|
3990
|
+
retrievers: SEARCH_CLASSES.map(
|
|
3991
|
+
(cls) => ftsRetriever(graph.spans, {
|
|
3992
|
+
name: cls.name,
|
|
3993
|
+
scope: cls.scope,
|
|
3994
|
+
cap: capFor(cls, limit)
|
|
3995
|
+
})
|
|
3996
|
+
),
|
|
3997
|
+
fusion: {
|
|
3998
|
+
weights: Object.fromEntries(SEARCH_CLASSES.map((cls) => [cls.name, cls.weight]))
|
|
3999
|
+
}
|
|
4000
|
+
});
|
|
4001
|
+
const response = await engine.search(query, { limit });
|
|
4002
|
+
const resolved = await resolveHits(
|
|
4003
|
+
graph,
|
|
4004
|
+
response.results,
|
|
4005
|
+
activeRoot,
|
|
4006
|
+
options.excerptWidth ?? 160
|
|
4007
|
+
);
|
|
4008
|
+
const boosted = options.initiative ? resolved.map(
|
|
4009
|
+
(hit) => hit.initiative === options.initiative ? { ...hit, score: hit.score + AFFINITY_BOOST } : hit
|
|
4010
|
+
).sort((a, b) => b.score - a.score) : resolved;
|
|
4011
|
+
return {
|
|
4012
|
+
hits: boosted.slice(0, limit),
|
|
4013
|
+
degraded: response.degraded,
|
|
4014
|
+
timingsMs: response.timingsMs
|
|
4015
|
+
};
|
|
4016
|
+
} finally {
|
|
4017
|
+
if (owned) graph.db.close();
|
|
4018
|
+
}
|
|
4019
|
+
}
|
|
4020
|
+
|
|
4021
|
+
// src/commands/search.ts
|
|
4022
|
+
var ArgsSchema32 = z33.object({
|
|
4023
|
+
query: z33.string().min(1),
|
|
4024
|
+
limit: z33.number().int().positive().max(100).optional(),
|
|
4025
|
+
initiative: z33.string().min(1).optional()
|
|
4026
|
+
});
|
|
4027
|
+
var HitSchema = z33.object({
|
|
4028
|
+
ref: z33.string(),
|
|
4029
|
+
class: z33.string(),
|
|
4030
|
+
initiative: z33.string().nullable(),
|
|
4031
|
+
title: z33.string().nullable(),
|
|
4032
|
+
path: z33.string().nullable(),
|
|
4033
|
+
excerpt: z33.string().nullable(),
|
|
4034
|
+
score: z33.number(),
|
|
4035
|
+
sources: z33.array(z33.string())
|
|
4036
|
+
});
|
|
4037
|
+
var ResultSchema29 = z33.object({
|
|
4038
|
+
query: z33.string(),
|
|
4039
|
+
hits: z33.array(HitSchema),
|
|
4040
|
+
// A retriever that failed contributed nothing and is named here. The search
|
|
4041
|
+
// still answers, with less; an index is allowed to be partly broken.
|
|
4042
|
+
degraded: z33.array(z33.object({ retriever: z33.string(), reason: z33.string(), message: z33.string() }))
|
|
4043
|
+
});
|
|
4044
|
+
var search_default = defineCommand({
|
|
4045
|
+
name: "search",
|
|
4046
|
+
description: "Search every initiative at once: notes, briefs, sources, tasks, session records and mined transcripts.",
|
|
4047
|
+
args: ArgsSchema32,
|
|
4048
|
+
result: ResultSchema29,
|
|
4049
|
+
cli: {
|
|
4050
|
+
positional: ["query"],
|
|
4051
|
+
options: {
|
|
4052
|
+
limit: { long: "--limit", description: "How many results to return (default 10)" },
|
|
4053
|
+
initiative: {
|
|
4054
|
+
long: "--initiative",
|
|
4055
|
+
description: "Bias towards this initiative. A boost, never a filter \u2014 foreign hits still rank."
|
|
4056
|
+
}
|
|
4057
|
+
},
|
|
4058
|
+
usage: "active-work search <query> [--limit 10] [--initiative <slug>]"
|
|
4059
|
+
},
|
|
4060
|
+
async run(args) {
|
|
4061
|
+
const { hits, degraded } = await searchWorkspace(args.query, {
|
|
4062
|
+
limit: args.limit,
|
|
4063
|
+
initiative: args.initiative
|
|
4064
|
+
});
|
|
4065
|
+
return {
|
|
4066
|
+
query: args.query,
|
|
4067
|
+
hits,
|
|
4068
|
+
degraded: degraded.map((entry) => ({
|
|
4069
|
+
retriever: entry.retriever,
|
|
4070
|
+
reason: entry.reason,
|
|
4071
|
+
message: entry.message
|
|
4072
|
+
}))
|
|
4073
|
+
};
|
|
4074
|
+
}
|
|
4075
|
+
});
|
|
4076
|
+
|
|
4077
|
+
// src/commands/list.ts
|
|
4078
|
+
import { z as z34 } from "zod";
|
|
4079
|
+
var argsSchema2 = z34.object({}).strict();
|
|
4080
|
+
var itemSchema = z34.object({
|
|
4081
|
+
slug: z34.string(),
|
|
4082
|
+
title: z34.string(),
|
|
4083
|
+
state: z34.enum(["focused", "backburner", "paused", "done"]),
|
|
4084
|
+
rank: z34.number().int().positive().optional(),
|
|
4085
|
+
ship_target: z34.string().optional(),
|
|
4086
|
+
paused_since: z34.string().optional(),
|
|
4087
|
+
updated: z34.string()
|
|
4088
|
+
});
|
|
4089
|
+
var sectionSchema = z34.object({
|
|
4090
|
+
heading: z34.string(),
|
|
4091
|
+
items: z34.array(itemSchema)
|
|
4092
|
+
});
|
|
4093
|
+
var parseErrorSchema2 = z34.object({
|
|
4094
|
+
slug: z34.string(),
|
|
4095
|
+
error: z34.string()
|
|
4096
|
+
});
|
|
4097
|
+
var resultSchema2 = z34.object({
|
|
4098
|
+
sections: z34.array(sectionSchema),
|
|
4099
|
+
parse_errors: z34.array(parseErrorSchema2)
|
|
3875
4100
|
});
|
|
3876
4101
|
function toItem(slug, fm) {
|
|
3877
4102
|
return {
|
|
@@ -3946,24 +4171,24 @@ var list_default = defineCommand({
|
|
|
3946
4171
|
});
|
|
3947
4172
|
|
|
3948
4173
|
// src/commands/worktree-set.ts
|
|
3949
|
-
import
|
|
3950
|
-
import { z as
|
|
3951
|
-
var argsSchema3 =
|
|
3952
|
-
slug:
|
|
3953
|
-
path:
|
|
3954
|
-
label:
|
|
3955
|
-
default:
|
|
4174
|
+
import path36 from "path";
|
|
4175
|
+
import { z as z35 } from "zod";
|
|
4176
|
+
var argsSchema3 = z35.object({
|
|
4177
|
+
slug: z35.string().min(1),
|
|
4178
|
+
path: z35.string().min(1),
|
|
4179
|
+
label: z35.string().min(1).optional(),
|
|
4180
|
+
default: z35.boolean().optional()
|
|
3956
4181
|
});
|
|
3957
|
-
var resultSchema3 =
|
|
3958
|
-
slug:
|
|
3959
|
-
label:
|
|
3960
|
-
path:
|
|
3961
|
-
default:
|
|
4182
|
+
var resultSchema3 = z35.object({
|
|
4183
|
+
slug: z35.string(),
|
|
4184
|
+
label: z35.string(),
|
|
4185
|
+
path: z35.string(),
|
|
4186
|
+
default: z35.boolean(),
|
|
3962
4187
|
/** True when this promoted a worktree `wrap` had already swept (AW-67). */
|
|
3963
|
-
promoted:
|
|
4188
|
+
promoted: z35.boolean()
|
|
3964
4189
|
});
|
|
3965
4190
|
var DEFAULT_LABEL = "main";
|
|
3966
|
-
var samePath = (a, b) =>
|
|
4191
|
+
var samePath = (a, b) => path36.resolve(expandTilde(a)) === path36.resolve(expandTilde(b));
|
|
3967
4192
|
var worktree_set_default = defineCommand({
|
|
3968
4193
|
name: "worktree.set",
|
|
3969
4194
|
description: "Add or update a registered worktree on an existing initiative. A lone worktree is made default automatically; use --default to promote an added one. Registered worktrees live in artifacts.yml alongside the ones wrap sweeps, and are what `aw` resolves a cwd against.",
|
|
@@ -3985,8 +4210,8 @@ var worktree_set_default = defineCommand({
|
|
|
3985
4210
|
},
|
|
3986
4211
|
async run(args) {
|
|
3987
4212
|
const label = args.label ?? DEFAULT_LABEL;
|
|
3988
|
-
const initiativeDir =
|
|
3989
|
-
const briefPath =
|
|
4213
|
+
const initiativeDir = path36.join(getActiveRoot(), args.slug);
|
|
4214
|
+
const briefPath = path36.join(initiativeDir, "brief.md");
|
|
3990
4215
|
return withFileLock(getLockPath(args.slug), async () => {
|
|
3991
4216
|
let frontmatter2;
|
|
3992
4217
|
let body;
|
|
@@ -4040,15 +4265,15 @@ var worktree_set_default = defineCommand({
|
|
|
4040
4265
|
});
|
|
4041
4266
|
|
|
4042
4267
|
// src/commands/worktree-set-default.ts
|
|
4043
|
-
import
|
|
4044
|
-
import { z as
|
|
4045
|
-
var argsSchema4 =
|
|
4046
|
-
slug:
|
|
4047
|
-
label:
|
|
4268
|
+
import path37 from "path";
|
|
4269
|
+
import { z as z36 } from "zod";
|
|
4270
|
+
var argsSchema4 = z36.object({
|
|
4271
|
+
slug: z36.string().min(1),
|
|
4272
|
+
label: z36.string().min(1)
|
|
4048
4273
|
});
|
|
4049
|
-
var resultSchema4 =
|
|
4050
|
-
slug:
|
|
4051
|
-
default_label:
|
|
4274
|
+
var resultSchema4 = z36.object({
|
|
4275
|
+
slug: z36.string(),
|
|
4276
|
+
default_label: z36.string()
|
|
4052
4277
|
});
|
|
4053
4278
|
var worktree_set_default_default = defineCommand({
|
|
4054
4279
|
name: "worktree.set-default",
|
|
@@ -4059,8 +4284,8 @@ var worktree_set_default_default = defineCommand({
|
|
|
4059
4284
|
positional: ["slug", "label"]
|
|
4060
4285
|
},
|
|
4061
4286
|
async run({ slug, label }) {
|
|
4062
|
-
const initiativeDir =
|
|
4063
|
-
const briefPath =
|
|
4287
|
+
const initiativeDir = path37.join(getActiveRoot(), slug);
|
|
4288
|
+
const briefPath = path37.join(initiativeDir, "brief.md");
|
|
4064
4289
|
return withFileLock(getLockPath(slug), async () => {
|
|
4065
4290
|
let frontmatter2;
|
|
4066
4291
|
let body;
|
|
@@ -4091,11 +4316,11 @@ var worktree_set_default_default = defineCommand({
|
|
|
4091
4316
|
});
|
|
4092
4317
|
|
|
4093
4318
|
// src/commands/discover.ts
|
|
4094
|
-
import { z as
|
|
4319
|
+
import { z as z37 } from "zod";
|
|
4095
4320
|
|
|
4096
4321
|
// src/discover/index.ts
|
|
4097
4322
|
import { promises as fs29 } from "fs";
|
|
4098
|
-
import
|
|
4323
|
+
import path41 from "path";
|
|
4099
4324
|
|
|
4100
4325
|
// src/discover/run-command.ts
|
|
4101
4326
|
import { spawn } from "child_process";
|
|
@@ -4192,13 +4417,13 @@ async function discoverGitHub(repos, run = runCommand) {
|
|
|
4192
4417
|
}
|
|
4193
4418
|
|
|
4194
4419
|
// src/discover/git.ts
|
|
4195
|
-
import
|
|
4420
|
+
import path38 from "path";
|
|
4196
4421
|
var BRANCH_LIMIT = 20;
|
|
4197
4422
|
async function discoverGit(repoPaths, run = runCommand) {
|
|
4198
4423
|
const hits = [];
|
|
4199
4424
|
const errors = [];
|
|
4200
4425
|
for (const repoPath of repoPaths) {
|
|
4201
|
-
const repoName =
|
|
4426
|
+
const repoName = path38.basename(repoPath);
|
|
4202
4427
|
await collectBranches(repoPath, repoName, hits, errors, run);
|
|
4203
4428
|
await collectWorktrees(repoPath, repoName, hits, errors, run);
|
|
4204
4429
|
await collectStashes(repoPath, repoName, hits, errors, run);
|
|
@@ -4313,14 +4538,14 @@ function errStr(err) {
|
|
|
4313
4538
|
|
|
4314
4539
|
// src/discover/projects.ts
|
|
4315
4540
|
import { promises as fs27 } from "fs";
|
|
4316
|
-
import
|
|
4541
|
+
import path39 from "path";
|
|
4317
4542
|
var MS_PER_DAY = 24 * 60 * 60 * 1e3;
|
|
4318
4543
|
var RECENT_THRESHOLD_DAYS = 30;
|
|
4319
4544
|
async function discoverProjects(projectsRoot) {
|
|
4320
4545
|
const hits = [];
|
|
4321
4546
|
const errors = [];
|
|
4322
4547
|
if (!projectsRoot) return { hits, errors };
|
|
4323
|
-
const resolved =
|
|
4548
|
+
const resolved = path39.resolve(expandTilde(projectsRoot));
|
|
4324
4549
|
let entries;
|
|
4325
4550
|
try {
|
|
4326
4551
|
entries = await fs27.readdir(resolved, { withFileTypes: true });
|
|
@@ -4336,7 +4561,7 @@ async function discoverProjects(projectsRoot) {
|
|
|
4336
4561
|
if (!entry.isDirectory()) continue;
|
|
4337
4562
|
if (entry.name.startsWith(".")) continue;
|
|
4338
4563
|
if (entry.name === "active") continue;
|
|
4339
|
-
const fullPath =
|
|
4564
|
+
const fullPath = path39.join(resolved, entry.name);
|
|
4340
4565
|
let mtimeMs = 0;
|
|
4341
4566
|
try {
|
|
4342
4567
|
const stat = await fs27.stat(fullPath);
|
|
@@ -4369,11 +4594,11 @@ async function discoverProjects(projectsRoot) {
|
|
|
4369
4594
|
// src/discover/claude.ts
|
|
4370
4595
|
import { promises as fs28 } from "fs";
|
|
4371
4596
|
import os2 from "os";
|
|
4372
|
-
import
|
|
4597
|
+
import path40 from "path";
|
|
4373
4598
|
var MAX_SCAN_LINES = 200;
|
|
4374
4599
|
var COMPACTION_SUBJECT_PREFIX = "[compaction] ";
|
|
4375
4600
|
async function discoverClaudeSessions() {
|
|
4376
|
-
const root = process.env.CLAUDE_PROJECTS_ROOT ??
|
|
4601
|
+
const root = process.env.CLAUDE_PROJECTS_ROOT ?? path40.join(os2.homedir(), ".claude", "projects");
|
|
4377
4602
|
const hits = [];
|
|
4378
4603
|
const errors = [];
|
|
4379
4604
|
let projectDirs;
|
|
@@ -4388,7 +4613,7 @@ async function discoverClaudeSessions() {
|
|
|
4388
4613
|
const byCwd = /* @__PURE__ */ new Map();
|
|
4389
4614
|
for (const dir of projectDirs) {
|
|
4390
4615
|
if (!dir.isDirectory()) continue;
|
|
4391
|
-
const dirPath =
|
|
4616
|
+
const dirPath = path40.join(root, dir.name);
|
|
4392
4617
|
let files;
|
|
4393
4618
|
try {
|
|
4394
4619
|
files = await fs28.readdir(dirPath, { withFileTypes: true });
|
|
@@ -4401,7 +4626,7 @@ async function discoverClaudeSessions() {
|
|
|
4401
4626
|
}
|
|
4402
4627
|
for (const file of files) {
|
|
4403
4628
|
if (!file.isFile() || !file.name.endsWith(".jsonl")) continue;
|
|
4404
|
-
const filePath =
|
|
4629
|
+
const filePath = path40.join(dirPath, file.name);
|
|
4405
4630
|
try {
|
|
4406
4631
|
await aggregateSession(filePath, byCwd);
|
|
4407
4632
|
} catch (err) {
|
|
@@ -4457,7 +4682,7 @@ async function aggregateSession(filePath, byCwd) {
|
|
|
4457
4682
|
}
|
|
4458
4683
|
if (!cwd) return;
|
|
4459
4684
|
const subject = lastCompactionSummary ? `${COMPACTION_SUBJECT_PREFIX}${truncate2(lastCompactionSummary, 120)}` : firstUserMessage ? truncate2(firstUserMessage, 120) : "";
|
|
4460
|
-
const sessionId =
|
|
4685
|
+
const sessionId = path40.basename(filePath, ".jsonl");
|
|
4461
4686
|
const existing = byCwd.get(cwd);
|
|
4462
4687
|
if (!existing) {
|
|
4463
4688
|
byCwd.set(cwd, {
|
|
@@ -4557,7 +4782,7 @@ async function loadSlugs(activeRoot) {
|
|
|
4557
4782
|
}
|
|
4558
4783
|
}
|
|
4559
4784
|
async function loadTriagedRefs(activeRoot) {
|
|
4560
|
-
const logPath =
|
|
4785
|
+
const logPath = path41.join(activeRoot, ".triaged.log");
|
|
4561
4786
|
const refs = /* @__PURE__ */ new Set();
|
|
4562
4787
|
try {
|
|
4563
4788
|
const raw = await fs29.readFile(logPath, "utf8");
|
|
@@ -4583,28 +4808,28 @@ function matchSlug(hit, slugs) {
|
|
|
4583
4808
|
}
|
|
4584
4809
|
|
|
4585
4810
|
// src/commands/discover.ts
|
|
4586
|
-
var
|
|
4587
|
-
github_repos:
|
|
4588
|
-
local_repos:
|
|
4589
|
-
projects_root:
|
|
4590
|
-
});
|
|
4591
|
-
var
|
|
4592
|
-
source:
|
|
4593
|
-
ref:
|
|
4594
|
-
detail:
|
|
4595
|
-
metadata:
|
|
4596
|
-
slug_match:
|
|
4597
|
-
untracked:
|
|
4598
|
-
});
|
|
4599
|
-
var
|
|
4600
|
-
hits:
|
|
4601
|
-
errors:
|
|
4811
|
+
var ArgsSchema33 = z37.object({
|
|
4812
|
+
github_repos: z37.array(z37.string().min(1)).optional(),
|
|
4813
|
+
local_repos: z37.array(z37.string().min(1)).optional(),
|
|
4814
|
+
projects_root: z37.string().optional()
|
|
4815
|
+
});
|
|
4816
|
+
var HitSchema2 = z37.object({
|
|
4817
|
+
source: z37.string(),
|
|
4818
|
+
ref: z37.string(),
|
|
4819
|
+
detail: z37.string(),
|
|
4820
|
+
metadata: z37.record(z37.string(), z37.unknown()).optional(),
|
|
4821
|
+
slug_match: z37.string().optional(),
|
|
4822
|
+
untracked: z37.boolean().optional()
|
|
4823
|
+
});
|
|
4824
|
+
var ResultSchema30 = z37.object({
|
|
4825
|
+
hits: z37.array(HitSchema2),
|
|
4826
|
+
errors: z37.array(z37.object({ source: z37.string(), error: z37.string() }))
|
|
4602
4827
|
});
|
|
4603
4828
|
var discover_default = defineCommand({
|
|
4604
4829
|
name: "discover",
|
|
4605
4830
|
description: "Scan configured sources (gh PRs, local git, projects root, Claude sessions) and emit unfiltered discovery hits.",
|
|
4606
|
-
args:
|
|
4607
|
-
result:
|
|
4831
|
+
args: ArgsSchema33,
|
|
4832
|
+
result: ResultSchema30,
|
|
4608
4833
|
cli: {
|
|
4609
4834
|
options: {
|
|
4610
4835
|
github_repos: {
|
|
@@ -4631,15 +4856,15 @@ var discover_default = defineCommand({
|
|
|
4631
4856
|
});
|
|
4632
4857
|
|
|
4633
4858
|
// src/commands/drop.ts
|
|
4634
|
-
import { z as
|
|
4859
|
+
import { z as z38 } from "zod";
|
|
4635
4860
|
|
|
4636
4861
|
// src/discover/triaged-log.ts
|
|
4637
4862
|
import { promises as fs30 } from "fs";
|
|
4638
|
-
import
|
|
4863
|
+
import path42 from "path";
|
|
4639
4864
|
async function appendTriagedLog(action, ref, extra) {
|
|
4640
4865
|
const root = getActiveRoot();
|
|
4641
4866
|
await fs30.mkdir(root, { recursive: true });
|
|
4642
|
-
const logPath =
|
|
4867
|
+
const logPath = path42.join(root, ".triaged.log");
|
|
4643
4868
|
let existing = "";
|
|
4644
4869
|
try {
|
|
4645
4870
|
existing = await fs30.readFile(logPath, "utf8");
|
|
@@ -4652,18 +4877,18 @@ async function appendTriagedLog(action, ref, extra) {
|
|
|
4652
4877
|
}
|
|
4653
4878
|
|
|
4654
4879
|
// src/commands/drop.ts
|
|
4655
|
-
var
|
|
4656
|
-
ref:
|
|
4657
|
-
reason:
|
|
4880
|
+
var ArgsSchema34 = z38.object({
|
|
4881
|
+
ref: z38.string().min(1),
|
|
4882
|
+
reason: z38.string().optional()
|
|
4658
4883
|
});
|
|
4659
|
-
var
|
|
4660
|
-
ref:
|
|
4884
|
+
var ResultSchema31 = z38.object({
|
|
4885
|
+
ref: z38.string()
|
|
4661
4886
|
});
|
|
4662
4887
|
var drop_default = defineCommand({
|
|
4663
4888
|
name: "drop",
|
|
4664
4889
|
description: "Mark a discover hit as dropped so future discovers suppress it.",
|
|
4665
|
-
args:
|
|
4666
|
-
result:
|
|
4890
|
+
args: ArgsSchema34,
|
|
4891
|
+
result: ResultSchema31,
|
|
4667
4892
|
cli: {
|
|
4668
4893
|
positional: ["ref"],
|
|
4669
4894
|
options: {
|
|
@@ -4681,23 +4906,23 @@ var drop_default = defineCommand({
|
|
|
4681
4906
|
|
|
4682
4907
|
// src/commands/fold.ts
|
|
4683
4908
|
import { promises as fs31 } from "fs";
|
|
4684
|
-
import
|
|
4685
|
-
import { z as
|
|
4686
|
-
var
|
|
4687
|
-
ref:
|
|
4688
|
-
into:
|
|
4689
|
-
note:
|
|
4909
|
+
import path43 from "path";
|
|
4910
|
+
import { z as z39 } from "zod";
|
|
4911
|
+
var ArgsSchema35 = z39.object({
|
|
4912
|
+
ref: z39.string().min(1),
|
|
4913
|
+
into: z39.string().min(1),
|
|
4914
|
+
note: z39.string().optional()
|
|
4690
4915
|
});
|
|
4691
|
-
var
|
|
4692
|
-
ref:
|
|
4693
|
-
into:
|
|
4694
|
-
session_file:
|
|
4916
|
+
var ResultSchema32 = z39.object({
|
|
4917
|
+
ref: z39.string(),
|
|
4918
|
+
into: z39.string(),
|
|
4919
|
+
session_file: z39.string()
|
|
4695
4920
|
});
|
|
4696
4921
|
var fold_default = defineCommand({
|
|
4697
4922
|
name: "fold",
|
|
4698
4923
|
description: "Mark a discover hit as folded into an existing initiative.",
|
|
4699
|
-
args:
|
|
4700
|
-
result:
|
|
4924
|
+
args: ArgsSchema35,
|
|
4925
|
+
result: ResultSchema32,
|
|
4701
4926
|
cli: {
|
|
4702
4927
|
positional: ["ref"],
|
|
4703
4928
|
options: {
|
|
@@ -4723,7 +4948,7 @@ var fold_default = defineCommand({
|
|
|
4723
4948
|
if (err instanceof NotFoundError) throw err;
|
|
4724
4949
|
throw new NotFoundError(`Initiative not found: ${args.into}`);
|
|
4725
4950
|
}
|
|
4726
|
-
const sessionsDir =
|
|
4951
|
+
const sessionsDir = path43.join(initiativeDir, "sessions");
|
|
4727
4952
|
await fs31.mkdir(sessionsDir, { recursive: true });
|
|
4728
4953
|
const startedIso = nowIso();
|
|
4729
4954
|
const stem = buildSessionStem(startedIso, `folded-${sanitizeRef(args.ref)}`);
|
|
@@ -4756,27 +4981,27 @@ function sanitizeRef(ref) {
|
|
|
4756
4981
|
|
|
4757
4982
|
// src/commands/track.ts
|
|
4758
4983
|
import { promises as fs32 } from "fs";
|
|
4759
|
-
import
|
|
4760
|
-
import { z as
|
|
4984
|
+
import path44 from "path";
|
|
4985
|
+
import { z as z40 } from "zod";
|
|
4761
4986
|
import { stringify as yamlStringify } from "yaml";
|
|
4762
|
-
var
|
|
4763
|
-
ref:
|
|
4764
|
-
slug:
|
|
4765
|
-
title:
|
|
4766
|
-
ship_target:
|
|
4767
|
-
owner:
|
|
4768
|
-
worktree:
|
|
4769
|
-
});
|
|
4770
|
-
var
|
|
4771
|
-
slug:
|
|
4772
|
-
dir:
|
|
4773
|
-
ref:
|
|
4987
|
+
var ArgsSchema36 = z40.object({
|
|
4988
|
+
ref: z40.string().min(1),
|
|
4989
|
+
slug: z40.string().min(1),
|
|
4990
|
+
title: z40.string().optional(),
|
|
4991
|
+
ship_target: z40.string().optional(),
|
|
4992
|
+
owner: z40.string().optional(),
|
|
4993
|
+
worktree: z40.string().optional()
|
|
4994
|
+
});
|
|
4995
|
+
var ResultSchema33 = z40.object({
|
|
4996
|
+
slug: z40.string(),
|
|
4997
|
+
dir: z40.string(),
|
|
4998
|
+
ref: z40.string()
|
|
4774
4999
|
});
|
|
4775
5000
|
var track_default = defineCommand({
|
|
4776
5001
|
name: "track",
|
|
4777
5002
|
description: "Scaffold a new initiative from a discover hit.",
|
|
4778
|
-
args:
|
|
4779
|
-
result:
|
|
5003
|
+
args: ArgsSchema36,
|
|
5004
|
+
result: ResultSchema33,
|
|
4780
5005
|
cli: {
|
|
4781
5006
|
positional: ["ref"],
|
|
4782
5007
|
options: {
|
|
@@ -4803,13 +5028,13 @@ var track_default = defineCommand({
|
|
|
4803
5028
|
if (await dirExists5(dir)) {
|
|
4804
5029
|
throw new UsageError(`Initiative already exists: ${args.slug}`);
|
|
4805
5030
|
}
|
|
4806
|
-
await fs32.mkdir(
|
|
4807
|
-
await fs32.mkdir(
|
|
4808
|
-
await fs32.mkdir(
|
|
5031
|
+
await fs32.mkdir(path44.join(dir, "tasks"), { recursive: true });
|
|
5032
|
+
await fs32.mkdir(path44.join(dir, "sessions"), { recursive: true });
|
|
5033
|
+
await fs32.mkdir(path44.join(dir, "sources"), { recursive: true });
|
|
4809
5034
|
const title = args.title ?? deriveTitle(args.slug);
|
|
4810
5035
|
const briefBody = buildBriefBody(title, args.ref);
|
|
4811
5036
|
await writeFrontmatter(
|
|
4812
|
-
|
|
5037
|
+
path44.join(dir, "brief.md"),
|
|
4813
5038
|
{
|
|
4814
5039
|
schema_version: 1,
|
|
4815
5040
|
title,
|
|
@@ -4825,8 +5050,8 @@ var track_default = defineCommand({
|
|
|
4825
5050
|
const artifacts = ArtifactsSchema.parse({
|
|
4826
5051
|
worktrees: args.worktree ? [{ path: args.worktree, repo: args.worktree, name: "main", default: true }] : []
|
|
4827
5052
|
});
|
|
4828
|
-
await atomicWrite(
|
|
4829
|
-
await atomicWrite(
|
|
5053
|
+
await atomicWrite(path44.join(dir, "artifacts.yml"), yamlStringify(artifacts));
|
|
5054
|
+
await atomicWrite(path44.join(dir, "sources", ".gitkeep"), "");
|
|
4830
5055
|
await appendTriagedLog("track", args.ref, `slug:${args.slug}`);
|
|
4831
5056
|
return { slug: args.slug, dir, ref: args.ref };
|
|
4832
5057
|
}
|
|
@@ -4856,24 +5081,26 @@ function buildBriefBody(title, ref) {
|
|
|
4856
5081
|
}
|
|
4857
5082
|
|
|
4858
5083
|
// src/commands/prompt.ts
|
|
4859
|
-
import { z as
|
|
4860
|
-
var
|
|
4861
|
-
slug:
|
|
4862
|
-
offline:
|
|
5084
|
+
import { z as z41 } from "zod";
|
|
5085
|
+
var ArgsSchema37 = z41.object({
|
|
5086
|
+
slug: z41.string().min(1).optional(),
|
|
5087
|
+
offline: z41.boolean().optional(),
|
|
4863
5088
|
// Directory to resolve the initiative from when no slug is given. Falls back
|
|
4864
5089
|
// to the interactive-surface context cwd; unset for daemon/MCP callers.
|
|
4865
|
-
cwd:
|
|
5090
|
+
cwd: z41.string().min(1).optional(),
|
|
4866
5091
|
// Frame the prompt as ad-hoc work on the workstream rather than a
|
|
4867
5092
|
// continuation of its handoff / top task.
|
|
4868
|
-
adhoc:
|
|
5093
|
+
adhoc: z41.boolean().optional(),
|
|
5094
|
+
// Rank the notes against this instead of the top task and brief titles.
|
|
5095
|
+
about: z41.string().min(1).optional(),
|
|
4869
5096
|
// Skip the check for another session already live on this initiative.
|
|
4870
|
-
no_sibling_check:
|
|
5097
|
+
no_sibling_check: z41.boolean().optional()
|
|
4871
5098
|
});
|
|
4872
5099
|
var promptCommand = defineCommand({
|
|
4873
5100
|
name: "prompt",
|
|
4874
5101
|
description: "Print the bootstrap prompt for an initiative \u2014 the same text `aw` feeds Claude at launch \u2014 without any side effects. Resolves the initiative from a slug or the caller's cwd. Use it to re-seed context in a running session.",
|
|
4875
|
-
args:
|
|
4876
|
-
result:
|
|
5102
|
+
args: ArgsSchema37,
|
|
5103
|
+
result: z41.string(),
|
|
4877
5104
|
cli: {
|
|
4878
5105
|
positional: ["slug"],
|
|
4879
5106
|
options: {
|
|
@@ -4889,12 +5116,16 @@ var promptCommand = defineCommand({
|
|
|
4889
5116
|
long: "--adhoc",
|
|
4890
5117
|
description: "Frame the prompt as ad-hoc work on the workstream, awaiting the user\u2019s task, not a continuation of the handoff / top task."
|
|
4891
5118
|
},
|
|
5119
|
+
about: {
|
|
5120
|
+
long: "--about",
|
|
5121
|
+
description: "What this session is about, ranking the notes against it instead of the top task and brief titles."
|
|
5122
|
+
},
|
|
4892
5123
|
no_sibling_check: {
|
|
4893
5124
|
long: "--no-sibling-check",
|
|
4894
5125
|
description: "Skip the check for another session already live on this initiative."
|
|
4895
5126
|
}
|
|
4896
5127
|
},
|
|
4897
|
-
usage: "active-work prompt [slug] [--offline] [--cwd <dir>] [--adhoc] [--no-sibling-check]"
|
|
5128
|
+
usage: "active-work prompt [slug] [--offline] [--cwd <dir>] [--adhoc] [--about <text>] [--no-sibling-check]"
|
|
4898
5129
|
},
|
|
4899
5130
|
async run(args, ctx) {
|
|
4900
5131
|
const activeRoot = ctx.activeRoot ?? getActiveRoot();
|
|
@@ -4916,6 +5147,7 @@ var promptCommand = defineCommand({
|
|
|
4916
5147
|
slug,
|
|
4917
5148
|
includeLiveStatus: !args.offline,
|
|
4918
5149
|
adhoc: args.adhoc,
|
|
5150
|
+
...args.about !== void 0 ? { about: args.about } : {},
|
|
4919
5151
|
detectSiblings: !args.no_sibling_check && !args.offline,
|
|
4920
5152
|
...process.env.AW_LEASE_ID ? { ownLeaseId: process.env.AW_LEASE_ID } : {}
|
|
4921
5153
|
});
|
|
@@ -4926,19 +5158,19 @@ var prompt_default = promptCommand;
|
|
|
4926
5158
|
|
|
4927
5159
|
// src/commands/edit.ts
|
|
4928
5160
|
import { promises as fs33 } from "fs";
|
|
4929
|
-
import
|
|
5161
|
+
import path45 from "path";
|
|
4930
5162
|
import { spawn as spawn2 } from "child_process";
|
|
4931
|
-
import { z as
|
|
4932
|
-
var
|
|
4933
|
-
slug:
|
|
4934
|
-
target:
|
|
5163
|
+
import { z as z42 } from "zod";
|
|
5164
|
+
var ArgsSchema38 = z42.object({
|
|
5165
|
+
slug: z42.string().min(1),
|
|
5166
|
+
target: z42.enum(["brief"]).default("brief")
|
|
4935
5167
|
});
|
|
4936
|
-
var
|
|
4937
|
-
slug:
|
|
4938
|
-
target:
|
|
4939
|
-
file:
|
|
4940
|
-
validated:
|
|
4941
|
-
aborted:
|
|
5168
|
+
var ResultSchema34 = z42.object({
|
|
5169
|
+
slug: z42.string(),
|
|
5170
|
+
target: z42.enum(["brief"]),
|
|
5171
|
+
file: z42.string(),
|
|
5172
|
+
validated: z42.boolean(),
|
|
5173
|
+
aborted: z42.boolean().optional()
|
|
4942
5174
|
});
|
|
4943
5175
|
async function resolveEditor(filePath) {
|
|
4944
5176
|
const editorEnv = process.env.EDITOR;
|
|
@@ -4977,7 +5209,7 @@ var defaultDeps = {
|
|
|
4977
5209
|
spawner: defaultSpawner
|
|
4978
5210
|
};
|
|
4979
5211
|
function targetFile(slug) {
|
|
4980
|
-
return
|
|
5212
|
+
return path45.join(getInitiativeDir(slug), "brief.md");
|
|
4981
5213
|
}
|
|
4982
5214
|
async function fileExists2(p) {
|
|
4983
5215
|
try {
|
|
@@ -5025,8 +5257,8 @@ ${message}`,
|
|
|
5025
5257
|
var edit = defineCommand({
|
|
5026
5258
|
name: "edit",
|
|
5027
5259
|
description: "Open the operator's editor on brief.md.",
|
|
5028
|
-
args:
|
|
5029
|
-
result:
|
|
5260
|
+
args: ArgsSchema38,
|
|
5261
|
+
result: ResultSchema34,
|
|
5030
5262
|
cli: {
|
|
5031
5263
|
positional: ["slug", "target"],
|
|
5032
5264
|
usage: "active-work edit <slug> [brief]"
|
|
@@ -5039,7 +5271,7 @@ var edit_default = edit;
|
|
|
5039
5271
|
|
|
5040
5272
|
// src/commands/mcp-serve.ts
|
|
5041
5273
|
import { spawn as spawn3 } from "child_process";
|
|
5042
|
-
import { z as
|
|
5274
|
+
import { z as z44 } from "zod";
|
|
5043
5275
|
|
|
5044
5276
|
// src/server/mcp.ts
|
|
5045
5277
|
import {
|
|
@@ -5056,7 +5288,7 @@ import {
|
|
|
5056
5288
|
} from "@titan-design/registry";
|
|
5057
5289
|
|
|
5058
5290
|
// src/version.ts
|
|
5059
|
-
var BUILD_VERSION = "0.
|
|
5291
|
+
var BUILD_VERSION = "0.7.0";
|
|
5060
5292
|
|
|
5061
5293
|
// src/server/mcp.ts
|
|
5062
5294
|
var TOOL_NAME_PREFIX = "active__";
|
|
@@ -5079,7 +5311,7 @@ import { DaemonAlreadyRunningError, startDaemon } from "@titan-design/daemon";
|
|
|
5079
5311
|
|
|
5080
5312
|
// src/server/dashboard-routes.ts
|
|
5081
5313
|
import { promises as fs34 } from "fs";
|
|
5082
|
-
import
|
|
5314
|
+
import path46 from "path";
|
|
5083
5315
|
import { fileURLToPath } from "url";
|
|
5084
5316
|
var PLACEHOLDER_HTML = `<!doctype html>
|
|
5085
5317
|
<html lang="en">
|
|
@@ -5111,17 +5343,17 @@ var CONTENT_TYPES = {
|
|
|
5111
5343
|
".woff2": "font/woff2"
|
|
5112
5344
|
};
|
|
5113
5345
|
function contentTypeFor(filename) {
|
|
5114
|
-
const ext =
|
|
5346
|
+
const ext = path46.extname(filename).toLowerCase();
|
|
5115
5347
|
return CONTENT_TYPES[ext] ?? "application/octet-stream";
|
|
5116
5348
|
}
|
|
5117
5349
|
function dashboardDirCandidates() {
|
|
5118
|
-
const here =
|
|
5350
|
+
const here = path46.dirname(fileURLToPath(import.meta.url));
|
|
5119
5351
|
return [
|
|
5120
|
-
|
|
5352
|
+
path46.resolve(here, "dashboard"),
|
|
5121
5353
|
// bundled: dist/cli.js -> dist/dashboard
|
|
5122
|
-
|
|
5354
|
+
path46.resolve(here, "..", "dashboard"),
|
|
5123
5355
|
// legacy: dist/server -> dist/dashboard
|
|
5124
|
-
|
|
5356
|
+
path46.resolve(here, "..", "..", "dist", "dashboard")
|
|
5125
5357
|
// dev: src/server -> dist/dashboard
|
|
5126
5358
|
];
|
|
5127
5359
|
}
|
|
@@ -5147,13 +5379,13 @@ async function handleDashboard(c) {
|
|
|
5147
5379
|
const url = new URL(c.req.url);
|
|
5148
5380
|
const subpath = url.pathname.replace(/^\/ui\/?/, "");
|
|
5149
5381
|
const relative = subpath === "" ? "index.html" : subpath;
|
|
5150
|
-
const target =
|
|
5151
|
-
if (!target.startsWith(root +
|
|
5382
|
+
const target = path46.resolve(root, relative);
|
|
5383
|
+
if (!target.startsWith(root + path46.sep) && target !== root) {
|
|
5152
5384
|
return c.text("forbidden", 403);
|
|
5153
5385
|
}
|
|
5154
5386
|
const stat = await safeStat(target);
|
|
5155
5387
|
if (!stat.exists || !stat.isFile) {
|
|
5156
|
-
const indexPath =
|
|
5388
|
+
const indexPath = path46.join(root, "index.html");
|
|
5157
5389
|
const indexStat = await safeStat(indexPath);
|
|
5158
5390
|
if (!indexStat.exists) {
|
|
5159
5391
|
return c.html(PLACEHOLDER_HTML, 200);
|
|
@@ -5171,13 +5403,13 @@ async function handleDashboard(c) {
|
|
|
5171
5403
|
|
|
5172
5404
|
// src/server/logger.ts
|
|
5173
5405
|
import { mkdirSync, createWriteStream } from "fs";
|
|
5174
|
-
import
|
|
5406
|
+
import path47 from "path";
|
|
5175
5407
|
import pino, { multistream } from "pino";
|
|
5176
5408
|
var cachedLogger;
|
|
5177
5409
|
function buildLogger() {
|
|
5178
5410
|
const stateRoot = getStateRoot();
|
|
5179
5411
|
mkdirSync(stateRoot, { recursive: true });
|
|
5180
|
-
const logPath =
|
|
5412
|
+
const logPath = path47.join(stateRoot, "daemon.log");
|
|
5181
5413
|
const fileStream = createWriteStream(logPath, { flags: "a" });
|
|
5182
5414
|
const stderrIsTTY = process.stderr.isTTY === true;
|
|
5183
5415
|
const stderrStream = stderrIsTTY ? pino.transport({
|
|
@@ -5197,144 +5429,6 @@ import { existsSync } from "fs";
|
|
|
5197
5429
|
import { transcriptsRoot as transcriptsRoot2 } from "@titan-design/session-read";
|
|
5198
5430
|
import { watchTree } from "@titan-design/daemon";
|
|
5199
5431
|
|
|
5200
|
-
// src/session-index/graph.ts
|
|
5201
|
-
import Database from "better-sqlite3";
|
|
5202
|
-
import { openSessionGraph } from "@titan-design/session-graph";
|
|
5203
|
-
import { runMigrations, WatermarkTable } from "@titan-design/store-sqlite";
|
|
5204
|
-
import path46 from "path";
|
|
5205
|
-
|
|
5206
|
-
// src/workspace-index/schema.ts
|
|
5207
|
-
import { kitDdl } from "@titan-design/store-sqlite";
|
|
5208
|
-
import { MIGRATIONS as SESSION_GRAPH_MIGRATIONS } from "@titan-design/session-graph";
|
|
5209
|
-
var WORKSPACE_KIT = {
|
|
5210
|
-
watermark: "workspace_file",
|
|
5211
|
-
edge: "edge",
|
|
5212
|
-
spanFts: "search"
|
|
5213
|
-
};
|
|
5214
|
-
var WORKSPACE_SPAN_SOURCE_BASE = 1e9;
|
|
5215
|
-
var DOMAIN_DDL = `
|
|
5216
|
-
CREATE TABLE IF NOT EXISTS initiative (
|
|
5217
|
-
path TEXT PRIMARY KEY,
|
|
5218
|
-
initiative_ref TEXT NOT NULL UNIQUE,
|
|
5219
|
-
slug TEXT NOT NULL,
|
|
5220
|
-
title TEXT,
|
|
5221
|
-
state TEXT,
|
|
5222
|
-
rank INTEGER,
|
|
5223
|
-
ship_target TEXT,
|
|
5224
|
-
owner TEXT,
|
|
5225
|
-
task_prefix TEXT,
|
|
5226
|
-
updated TEXT
|
|
5227
|
-
);
|
|
5228
|
-
|
|
5229
|
-
CREATE TABLE IF NOT EXISTS note (
|
|
5230
|
-
path TEXT PRIMARY KEY,
|
|
5231
|
-
note_ref TEXT NOT NULL UNIQUE,
|
|
5232
|
-
initiative TEXT NOT NULL,
|
|
5233
|
-
filename TEXT NOT NULL,
|
|
5234
|
-
kind TEXT NOT NULL,
|
|
5235
|
-
title TEXT NOT NULL,
|
|
5236
|
-
created TEXT,
|
|
5237
|
-
tags TEXT,
|
|
5238
|
-
hits INTEGER NOT NULL DEFAULT 0,
|
|
5239
|
-
promoted_at TEXT
|
|
5240
|
-
);
|
|
5241
|
-
CREATE INDEX IF NOT EXISTS idx_note_initiative ON note(initiative);
|
|
5242
|
-
|
|
5243
|
-
CREATE TABLE IF NOT EXISTS workspace_task (
|
|
5244
|
-
path TEXT PRIMARY KEY,
|
|
5245
|
-
task_ref TEXT NOT NULL,
|
|
5246
|
-
initiative TEXT NOT NULL,
|
|
5247
|
-
task_id TEXT NOT NULL,
|
|
5248
|
-
title TEXT NOT NULL,
|
|
5249
|
-
status TEXT NOT NULL,
|
|
5250
|
-
priority INTEGER,
|
|
5251
|
-
severity TEXT,
|
|
5252
|
-
estimate REAL,
|
|
5253
|
-
tags TEXT,
|
|
5254
|
-
created TEXT,
|
|
5255
|
-
updated TEXT,
|
|
5256
|
-
done_at TEXT
|
|
5257
|
-
);
|
|
5258
|
-
CREATE INDEX IF NOT EXISTS idx_workspace_task_ref ON workspace_task(task_ref);
|
|
5259
|
-
|
|
5260
|
-
CREATE TABLE IF NOT EXISTS session_record (
|
|
5261
|
-
path TEXT PRIMARY KEY,
|
|
5262
|
-
session_ref TEXT NOT NULL,
|
|
5263
|
-
initiative TEXT NOT NULL,
|
|
5264
|
-
session_id TEXT NOT NULL,
|
|
5265
|
-
started TEXT,
|
|
5266
|
-
ended TEXT,
|
|
5267
|
-
track TEXT,
|
|
5268
|
-
parent_session_id TEXT
|
|
5269
|
-
);
|
|
5270
|
-
CREATE INDEX IF NOT EXISTS idx_session_record_ref ON session_record(session_ref);
|
|
5271
|
-
|
|
5272
|
-
CREATE TABLE IF NOT EXISTS source (
|
|
5273
|
-
path TEXT PRIMARY KEY,
|
|
5274
|
-
source_ref TEXT NOT NULL UNIQUE,
|
|
5275
|
-
initiative TEXT NOT NULL,
|
|
5276
|
-
title TEXT,
|
|
5277
|
-
kind TEXT,
|
|
5278
|
-
added TEXT
|
|
5279
|
-
);
|
|
5280
|
-
`;
|
|
5281
|
-
function nextVersion(chain) {
|
|
5282
|
-
return (chain[chain.length - 1]?.version ?? 0) + 1;
|
|
5283
|
-
}
|
|
5284
|
-
var SPAN_SOURCE_INDEX = `
|
|
5285
|
-
CREATE INDEX IF NOT EXISTS idx_search_span_source ON search_span(source_id);
|
|
5286
|
-
`;
|
|
5287
|
-
var WORKSPACE_MIGRATIONS = [
|
|
5288
|
-
{
|
|
5289
|
-
version: nextVersion(SESSION_GRAPH_MIGRATIONS),
|
|
5290
|
-
name: "workspace index tables",
|
|
5291
|
-
up: (db) => {
|
|
5292
|
-
db.exec(kitDdl({ watermark: WORKSPACE_KIT.watermark }));
|
|
5293
|
-
db.exec(DOMAIN_DDL);
|
|
5294
|
-
db.exec(SPAN_SOURCE_INDEX);
|
|
5295
|
-
}
|
|
5296
|
-
}
|
|
5297
|
-
];
|
|
5298
|
-
var PRESERVE_DDL = `
|
|
5299
|
-
CREATE TABLE IF NOT EXISTS preserved_row (
|
|
5300
|
-
table_name TEXT NOT NULL,
|
|
5301
|
-
identity TEXT NOT NULL,
|
|
5302
|
-
row_key TEXT NOT NULL,
|
|
5303
|
-
payload TEXT NOT NULL,
|
|
5304
|
-
origin TEXT NOT NULL,
|
|
5305
|
-
mode TEXT NOT NULL DEFAULT 'insert',
|
|
5306
|
-
preserved_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')),
|
|
5307
|
-
PRIMARY KEY (table_name, row_key)
|
|
5308
|
-
);
|
|
5309
|
-
`;
|
|
5310
|
-
var PRESERVE_MIGRATION = {
|
|
5311
|
-
version: nextVersion([...SESSION_GRAPH_MIGRATIONS, ...WORKSPACE_MIGRATIONS]),
|
|
5312
|
-
name: "preserved rows",
|
|
5313
|
-
up: (db) => db.exec(PRESERVE_DDL)
|
|
5314
|
-
};
|
|
5315
|
-
var MIGRATIONS = [
|
|
5316
|
-
...SESSION_GRAPH_MIGRATIONS,
|
|
5317
|
-
...WORKSPACE_MIGRATIONS,
|
|
5318
|
-
PRESERVE_MIGRATION
|
|
5319
|
-
];
|
|
5320
|
-
|
|
5321
|
-
// src/session-index/graph.ts
|
|
5322
|
-
var SCHEMA_VERSION = MIGRATIONS[MIGRATIONS.length - 1]?.version ?? 0;
|
|
5323
|
-
function defaultGraphPath() {
|
|
5324
|
-
return path46.join(getMinerRoot(), "graph.sqlite3");
|
|
5325
|
-
}
|
|
5326
|
-
function openGraph(dbPath = defaultGraphPath()) {
|
|
5327
|
-
const graph = openSessionGraph(dbPath);
|
|
5328
|
-
runMigrations(graph.db, MIGRATIONS);
|
|
5329
|
-
return {
|
|
5330
|
-
...graph,
|
|
5331
|
-
workspaceFiles: new WatermarkTable(graph.db, { name: WORKSPACE_KIT.watermark })
|
|
5332
|
-
};
|
|
5333
|
-
}
|
|
5334
|
-
function openGraphReadOnly(dbPath = defaultGraphPath()) {
|
|
5335
|
-
return new Database(dbPath, { readonly: true });
|
|
5336
|
-
}
|
|
5337
|
-
|
|
5338
5432
|
// src/session-index/refresh.ts
|
|
5339
5433
|
import path56 from "path";
|
|
5340
5434
|
import { promises as fs44 } from "fs";
|
|
@@ -5344,7 +5438,7 @@ import { refreshCorpus, resetIndex } from "@titan-design/session-graph";
|
|
|
5344
5438
|
|
|
5345
5439
|
// src/session-index/tasks.ts
|
|
5346
5440
|
import { promises as fs35 } from "fs";
|
|
5347
|
-
import
|
|
5441
|
+
import path48 from "path";
|
|
5348
5442
|
var AMBIGUOUS = null;
|
|
5349
5443
|
async function initiativeSlugs(root) {
|
|
5350
5444
|
try {
|
|
@@ -5356,7 +5450,7 @@ async function initiativeSlugs(root) {
|
|
|
5356
5450
|
}
|
|
5357
5451
|
}
|
|
5358
5452
|
async function readInitiative(root, slug) {
|
|
5359
|
-
const dir =
|
|
5453
|
+
const dir = path48.join(root, slug, "tasks");
|
|
5360
5454
|
let files;
|
|
5361
5455
|
try {
|
|
5362
5456
|
files = await fs35.readdir(dir);
|
|
@@ -5368,7 +5462,7 @@ async function readInitiative(root, slug) {
|
|
|
5368
5462
|
for (const file of files) {
|
|
5369
5463
|
if (!file.endsWith(".yml")) continue;
|
|
5370
5464
|
try {
|
|
5371
|
-
const task = await readYaml(
|
|
5465
|
+
const task = await readYaml(path48.join(dir, file), TaskSchema);
|
|
5372
5466
|
found.push([task.id, { initiative: slug, title: task.title, status: task.status }]);
|
|
5373
5467
|
} catch {
|
|
5374
5468
|
continue;
|
|
@@ -5401,22 +5495,7 @@ function taskResolver(root) {
|
|
|
5401
5495
|
// src/workspace-index/refresh.ts
|
|
5402
5496
|
import { promises as fs43 } from "fs";
|
|
5403
5497
|
import matter4 from "gray-matter";
|
|
5404
|
-
import { z as
|
|
5405
|
-
|
|
5406
|
-
// src/workspace-index/refs.ts
|
|
5407
|
-
import path48 from "path";
|
|
5408
|
-
import { refKind } from "@titan-design/store-sqlite";
|
|
5409
|
-
var initiativeRef = refKind("initiative");
|
|
5410
|
-
var noteRef = refKind("note");
|
|
5411
|
-
var taskRef = refKind("task");
|
|
5412
|
-
var sessionRef = refKind("session");
|
|
5413
|
-
var sourceRef = refKind("source");
|
|
5414
|
-
function toRelative(activeRoot, absolutePath) {
|
|
5415
|
-
return path48.relative(activeRoot, absolutePath).split(path48.sep).join("/");
|
|
5416
|
-
}
|
|
5417
|
-
function toAbsolute(activeRoot, relativePath) {
|
|
5418
|
-
return path48.join(activeRoot, ...relativePath.split("/"));
|
|
5419
|
-
}
|
|
5498
|
+
import { z as z43 } from "zod";
|
|
5420
5499
|
|
|
5421
5500
|
// src/workspace-index/mentions.ts
|
|
5422
5501
|
var TASK_ID = /(?<![A-Za-z0-9])([A-Za-z][A-Za-z0-9]*-\d+)(?![A-Za-z0-9])/g;
|
|
@@ -6032,7 +6111,7 @@ function isUnchanged(row, file) {
|
|
|
6032
6111
|
}
|
|
6033
6112
|
var BATCH = 200;
|
|
6034
6113
|
function describeFailure(err) {
|
|
6035
|
-
if (err instanceof
|
|
6114
|
+
if (err instanceof z43.ZodError) {
|
|
6036
6115
|
return err.issues.map((issue) => `${issue.path.join(".") || "(root)"}: ${issue.message}`).join("; ");
|
|
6037
6116
|
}
|
|
6038
6117
|
return err instanceof Error ? err.message : String(err);
|
|
@@ -6538,15 +6617,15 @@ async function runDaemon(options = {}) {
|
|
|
6538
6617
|
}
|
|
6539
6618
|
|
|
6540
6619
|
// src/commands/mcp-serve.ts
|
|
6541
|
-
var
|
|
6542
|
-
stdio:
|
|
6543
|
-
detach:
|
|
6544
|
-
port:
|
|
6620
|
+
var ArgsSchema39 = z44.object({
|
|
6621
|
+
stdio: z44.boolean().optional(),
|
|
6622
|
+
detach: z44.boolean().optional(),
|
|
6623
|
+
port: z44.number().int().positive().optional()
|
|
6545
6624
|
});
|
|
6546
|
-
var
|
|
6547
|
-
mode:
|
|
6548
|
-
pid:
|
|
6549
|
-
port:
|
|
6625
|
+
var ResultSchema35 = z44.object({
|
|
6626
|
+
mode: z44.enum(["stdio", "http", "detached"]),
|
|
6627
|
+
pid: z44.number().optional(),
|
|
6628
|
+
port: z44.number().optional()
|
|
6550
6629
|
});
|
|
6551
6630
|
function detachedSpawn(port) {
|
|
6552
6631
|
const entry = process.argv[1];
|
|
@@ -6568,8 +6647,8 @@ function detachedSpawn(port) {
|
|
|
6568
6647
|
var mcp_serve_default = defineCommand({
|
|
6569
6648
|
name: "mcp.serve",
|
|
6570
6649
|
description: "Start the MCP server. --stdio for stdio mode; --detach to fork the HTTP daemon; otherwise runs the HTTP daemon in the foreground.",
|
|
6571
|
-
args:
|
|
6572
|
-
result:
|
|
6650
|
+
args: ArgsSchema39,
|
|
6651
|
+
result: ResultSchema35,
|
|
6573
6652
|
cli: {
|
|
6574
6653
|
options: {
|
|
6575
6654
|
stdio: {
|
|
@@ -6601,11 +6680,11 @@ var mcp_serve_default = defineCommand({
|
|
|
6601
6680
|
});
|
|
6602
6681
|
|
|
6603
6682
|
// src/commands/mcp-stop.ts
|
|
6604
|
-
import { z as
|
|
6605
|
-
var
|
|
6606
|
-
var
|
|
6607
|
-
|
|
6608
|
-
|
|
6683
|
+
import { z as z45 } from "zod";
|
|
6684
|
+
var ArgsSchema40 = z45.object({});
|
|
6685
|
+
var ResultSchema36 = z45.union([
|
|
6686
|
+
z45.object({ stopped: z45.literal(true), pid: z45.number() }),
|
|
6687
|
+
z45.object({ stopped: z45.literal(false), reason: z45.string() })
|
|
6609
6688
|
]);
|
|
6610
6689
|
var SHUTDOWN_TIMEOUT_MS = 3e3;
|
|
6611
6690
|
var POLL_INTERVAL_MS = 100;
|
|
@@ -6620,8 +6699,8 @@ async function waitForExit(pid, timeoutMs) {
|
|
|
6620
6699
|
var mcp_stop_default = defineCommand({
|
|
6621
6700
|
name: "mcp.stop",
|
|
6622
6701
|
description: "Stop the running MCP HTTP daemon (sends SIGTERM, waits for exit).",
|
|
6623
|
-
args:
|
|
6624
|
-
result:
|
|
6702
|
+
args: ArgsSchema40,
|
|
6703
|
+
result: ResultSchema36,
|
|
6625
6704
|
async run() {
|
|
6626
6705
|
const pidEntry = await readPidFile();
|
|
6627
6706
|
if (!pidEntry) {
|
|
@@ -6650,13 +6729,13 @@ var mcp_stop_default = defineCommand({
|
|
|
6650
6729
|
|
|
6651
6730
|
// src/commands/mcp-restart.ts
|
|
6652
6731
|
import { spawn as spawn4 } from "child_process";
|
|
6653
|
-
import { z as
|
|
6654
|
-
var
|
|
6655
|
-
port:
|
|
6732
|
+
import { z as z46 } from "zod";
|
|
6733
|
+
var ArgsSchema41 = z46.object({
|
|
6734
|
+
port: z46.number().int().positive().optional()
|
|
6656
6735
|
});
|
|
6657
|
-
var
|
|
6658
|
-
pid:
|
|
6659
|
-
port:
|
|
6736
|
+
var ResultSchema37 = z46.object({
|
|
6737
|
+
pid: z46.number(),
|
|
6738
|
+
port: z46.number()
|
|
6660
6739
|
});
|
|
6661
6740
|
var SHUTDOWN_TIMEOUT_MS2 = 15e3;
|
|
6662
6741
|
var KILL_TIMEOUT_MS = 3e3;
|
|
@@ -6724,8 +6803,8 @@ async function confirmStarted(pid, port) {
|
|
|
6724
6803
|
var mcp_restart_default = defineCommand({
|
|
6725
6804
|
name: "mcp.restart",
|
|
6726
6805
|
description: "Restart the MCP HTTP daemon (stop, then spawn a fresh detached instance).",
|
|
6727
|
-
args:
|
|
6728
|
-
result:
|
|
6806
|
+
args: ArgsSchema41,
|
|
6807
|
+
result: ResultSchema37,
|
|
6729
6808
|
cli: {
|
|
6730
6809
|
options: {
|
|
6731
6810
|
port: {
|
|
@@ -6744,17 +6823,17 @@ var mcp_restart_default = defineCommand({
|
|
|
6744
6823
|
});
|
|
6745
6824
|
|
|
6746
6825
|
// src/commands/mcp-status.ts
|
|
6747
|
-
import { z as
|
|
6748
|
-
var
|
|
6749
|
-
var
|
|
6750
|
-
running:
|
|
6751
|
-
pid:
|
|
6752
|
-
port:
|
|
6753
|
-
version:
|
|
6754
|
-
uptime_ms:
|
|
6755
|
-
healthy:
|
|
6826
|
+
import { z as z47 } from "zod";
|
|
6827
|
+
var ArgsSchema42 = z47.object({});
|
|
6828
|
+
var ResultSchema38 = z47.object({
|
|
6829
|
+
running: z47.boolean(),
|
|
6830
|
+
pid: z47.number().optional(),
|
|
6831
|
+
port: z47.number().optional(),
|
|
6832
|
+
version: z47.string().optional(),
|
|
6833
|
+
uptime_ms: z47.number().optional(),
|
|
6834
|
+
healthy: z47.boolean().optional(),
|
|
6756
6835
|
/** Answering `/health` with no PID file naming it — see `removePidFile`. */
|
|
6757
|
-
orphaned:
|
|
6836
|
+
orphaned: z47.boolean().optional()
|
|
6758
6837
|
});
|
|
6759
6838
|
async function statusByPort(port) {
|
|
6760
6839
|
const health = await probeHealth(port);
|
|
@@ -6772,8 +6851,8 @@ async function statusByPort(port) {
|
|
|
6772
6851
|
var mcp_status_default = defineCommand({
|
|
6773
6852
|
name: "mcp.status",
|
|
6774
6853
|
description: "Report the MCP HTTP daemon status (pid, port, version, uptime).",
|
|
6775
|
-
args:
|
|
6776
|
-
result:
|
|
6854
|
+
args: ArgsSchema42,
|
|
6855
|
+
result: ResultSchema38,
|
|
6777
6856
|
async run() {
|
|
6778
6857
|
const entry = await readPidFile();
|
|
6779
6858
|
if (!entry) {
|
|
@@ -6807,19 +6886,19 @@ var mcp_status_default = defineCommand({
|
|
|
6807
6886
|
// src/commands/mcp-logs.ts
|
|
6808
6887
|
import { promises as fs45 } from "fs";
|
|
6809
6888
|
import path57 from "path";
|
|
6810
|
-
import { z as
|
|
6811
|
-
var
|
|
6812
|
-
lines:
|
|
6889
|
+
import { z as z48 } from "zod";
|
|
6890
|
+
var ArgsSchema43 = z48.object({
|
|
6891
|
+
lines: z48.number().int().positive().optional()
|
|
6813
6892
|
});
|
|
6814
|
-
var
|
|
6815
|
-
lines:
|
|
6893
|
+
var ResultSchema39 = z48.object({
|
|
6894
|
+
lines: z48.array(z48.string())
|
|
6816
6895
|
});
|
|
6817
6896
|
var DEFAULT_LINES = 50;
|
|
6818
6897
|
var mcp_logs_default = defineCommand({
|
|
6819
6898
|
name: "mcp.logs",
|
|
6820
6899
|
description: "Return the last N lines of the daemon log (default 50).",
|
|
6821
|
-
args:
|
|
6822
|
-
result:
|
|
6900
|
+
args: ArgsSchema43,
|
|
6901
|
+
result: ResultSchema39,
|
|
6823
6902
|
cli: {
|
|
6824
6903
|
options: {
|
|
6825
6904
|
lines: {
|
|
@@ -6849,7 +6928,7 @@ var mcp_logs_default = defineCommand({
|
|
|
6849
6928
|
});
|
|
6850
6929
|
|
|
6851
6930
|
// src/commands/miner-drain-ingest.ts
|
|
6852
|
-
import { z as
|
|
6931
|
+
import { z as z52 } from "zod";
|
|
6853
6932
|
|
|
6854
6933
|
// src/drain/transcript-reader.ts
|
|
6855
6934
|
import { nextOffset, prefixHash, readJsonLines, resumePoint } from "@titan-design/locator";
|
|
@@ -6863,29 +6942,29 @@ import { promises as fs46 } from "fs";
|
|
|
6863
6942
|
import path58 from "path";
|
|
6864
6943
|
|
|
6865
6944
|
// src/schemas/template.ts
|
|
6866
|
-
import { z as
|
|
6867
|
-
var LocatorSchema =
|
|
6868
|
-
|
|
6869
|
-
|
|
6870
|
-
|
|
6945
|
+
import { z as z49 } from "zod";
|
|
6946
|
+
var LocatorSchema = z49.tuple([
|
|
6947
|
+
z49.number().int().nonnegative(),
|
|
6948
|
+
z49.number().int().nonnegative(),
|
|
6949
|
+
z49.number().int().positive()
|
|
6871
6950
|
]);
|
|
6872
|
-
var TemplateSchema =
|
|
6873
|
-
templateId:
|
|
6874
|
-
toolType:
|
|
6875
|
-
maskedSignature:
|
|
6876
|
-
createdAt:
|
|
6877
|
-
occurrenceCount:
|
|
6951
|
+
var TemplateSchema = z49.object({
|
|
6952
|
+
templateId: z49.string().min(1),
|
|
6953
|
+
toolType: z49.string().min(1),
|
|
6954
|
+
maskedSignature: z49.string().min(1),
|
|
6955
|
+
createdAt: z49.string().min(1),
|
|
6956
|
+
occurrenceCount: z49.number().int().nonnegative(),
|
|
6878
6957
|
exemplarLocator: LocatorSchema
|
|
6879
6958
|
});
|
|
6880
|
-
var OccurrenceSchema =
|
|
6881
|
-
templateId:
|
|
6959
|
+
var OccurrenceSchema = z49.object({
|
|
6960
|
+
templateId: z49.string().min(1),
|
|
6882
6961
|
locator: LocatorSchema,
|
|
6883
|
-
sessionId:
|
|
6884
|
-
timestamp:
|
|
6885
|
-
extractedParams:
|
|
6962
|
+
sessionId: z49.string().min(1),
|
|
6963
|
+
timestamp: z49.string().min(1),
|
|
6964
|
+
extractedParams: z49.record(z49.string(), z49.string()).optional()
|
|
6886
6965
|
});
|
|
6887
|
-
var TemplatesFileSchema =
|
|
6888
|
-
templates:
|
|
6966
|
+
var TemplatesFileSchema = z49.object({
|
|
6967
|
+
templates: z49.array(TemplateSchema).default([])
|
|
6889
6968
|
});
|
|
6890
6969
|
|
|
6891
6970
|
// src/drain/store.ts
|
|
@@ -6932,27 +7011,27 @@ async function appendOccurrences(occurrences, root = getMinerRoot()) {
|
|
|
6932
7011
|
// src/drain/tree-store.ts
|
|
6933
7012
|
import { promises as fs47 } from "fs";
|
|
6934
7013
|
import path59 from "path";
|
|
6935
|
-
import { z as
|
|
6936
|
-
var PartitionSchema =
|
|
6937
|
-
partition:
|
|
6938
|
-
nextClusterId:
|
|
6939
|
-
clusters:
|
|
6940
|
-
|
|
6941
|
-
clusterId:
|
|
6942
|
-
tokens:
|
|
6943
|
-
size:
|
|
7014
|
+
import { z as z50 } from "zod";
|
|
7015
|
+
var PartitionSchema = z50.object({
|
|
7016
|
+
partition: z50.string().min(1),
|
|
7017
|
+
nextClusterId: z50.number().int().positive(),
|
|
7018
|
+
clusters: z50.array(
|
|
7019
|
+
z50.object({
|
|
7020
|
+
clusterId: z50.number().int().positive(),
|
|
7021
|
+
tokens: z50.array(z50.string()),
|
|
7022
|
+
size: z50.number().int().nonnegative()
|
|
6944
7023
|
})
|
|
6945
7024
|
),
|
|
6946
7025
|
/** `clusterId -> templateId`, as pairs so the file has a stable order. */
|
|
6947
|
-
templateIds:
|
|
7026
|
+
templateIds: z50.array(z50.tuple([z50.number().int().positive(), z50.string().min(1)]))
|
|
6948
7027
|
});
|
|
6949
|
-
var TreeSnapshotFileSchema =
|
|
6950
|
-
version:
|
|
6951
|
-
partitions:
|
|
7028
|
+
var TreeSnapshotFileSchema = z50.object({
|
|
7029
|
+
version: z50.literal(1).default(1),
|
|
7030
|
+
partitions: z50.array(PartitionSchema).default([])
|
|
6952
7031
|
});
|
|
6953
|
-
var LegacySnapshotFileSchema =
|
|
6954
|
-
version:
|
|
6955
|
-
trees:
|
|
7032
|
+
var LegacySnapshotFileSchema = z50.object({
|
|
7033
|
+
version: z50.literal(1),
|
|
7034
|
+
trees: z50.array(PartitionSchema.omit({ partition: true }).extend({ toolType: z50.string().min(1) }))
|
|
6956
7035
|
});
|
|
6957
7036
|
function snapshotPath(root) {
|
|
6958
7037
|
return path59.join(root, "drain-trees.json");
|
|
@@ -7135,23 +7214,23 @@ function extractBlobs(line, toolNames) {
|
|
|
7135
7214
|
// src/drain/reader-state.ts
|
|
7136
7215
|
import { promises as fs48 } from "fs";
|
|
7137
7216
|
import path60 from "path";
|
|
7138
|
-
import { z as
|
|
7139
|
-
var TranscriptStateSchema =
|
|
7217
|
+
import { z as z51 } from "zod";
|
|
7218
|
+
var TranscriptStateSchema = z51.object({
|
|
7140
7219
|
/** `~`-relative path, matching `session-index/discover.ts`'s display form. */
|
|
7141
|
-
path:
|
|
7142
|
-
lastByteOffset:
|
|
7220
|
+
path: z51.string().min(1),
|
|
7221
|
+
lastByteOffset: z51.number().int().nonnegative().default(0),
|
|
7143
7222
|
/** sha256 of bytes `[0, lastByteOffset)`; detects rewrite vs. append. */
|
|
7144
|
-
prefixHash:
|
|
7223
|
+
prefixHash: z51.string().nullable().default(null),
|
|
7145
7224
|
/**
|
|
7146
7225
|
* `tool_use_id -> tool name` pairs seen but not yet consumed by a result.
|
|
7147
7226
|
* Persisted because a chunk boundary routinely falls between an assistant's
|
|
7148
7227
|
* `tool_use` and the user line carrying its result.
|
|
7149
7228
|
*/
|
|
7150
|
-
pendingToolNames:
|
|
7229
|
+
pendingToolNames: z51.record(z51.string(), z51.string()).default({})
|
|
7151
7230
|
});
|
|
7152
|
-
var ReaderStateSchema =
|
|
7153
|
-
version:
|
|
7154
|
-
transcripts:
|
|
7231
|
+
var ReaderStateSchema = z51.object({
|
|
7232
|
+
version: z51.literal(1).default(1),
|
|
7233
|
+
transcripts: z51.array(TranscriptStateSchema).default([])
|
|
7155
7234
|
});
|
|
7156
7235
|
var MAX_PENDING_TOOL_NAMES = 256;
|
|
7157
7236
|
function readerStatePath(root = getMinerRoot()) {
|
|
@@ -7322,33 +7401,33 @@ async function runDrainIngest(options = {}) {
|
|
|
7322
7401
|
}
|
|
7323
7402
|
|
|
7324
7403
|
// src/commands/miner-drain-ingest.ts
|
|
7325
|
-
var
|
|
7326
|
-
full:
|
|
7327
|
-
limit:
|
|
7328
|
-
verify_hashes:
|
|
7329
|
-
});
|
|
7330
|
-
var
|
|
7331
|
-
startedAt:
|
|
7332
|
-
durationMs:
|
|
7333
|
-
transcripts:
|
|
7334
|
-
scanned:
|
|
7335
|
-
unchanged:
|
|
7336
|
-
rewound:
|
|
7337
|
-
linesRead:
|
|
7338
|
-
malformedLines:
|
|
7339
|
-
blobs:
|
|
7340
|
-
ingested:
|
|
7341
|
-
newTemplates:
|
|
7342
|
-
templates:
|
|
7343
|
-
evicting:
|
|
7344
|
-
curve:
|
|
7345
|
-
errors:
|
|
7404
|
+
var ArgsSchema44 = z52.object({
|
|
7405
|
+
full: z52.boolean().optional(),
|
|
7406
|
+
limit: z52.coerce.number().int().positive().optional(),
|
|
7407
|
+
verify_hashes: z52.boolean().optional()
|
|
7408
|
+
});
|
|
7409
|
+
var ResultSchema40 = z52.object({
|
|
7410
|
+
startedAt: z52.string(),
|
|
7411
|
+
durationMs: z52.number(),
|
|
7412
|
+
transcripts: z52.number(),
|
|
7413
|
+
scanned: z52.number(),
|
|
7414
|
+
unchanged: z52.number(),
|
|
7415
|
+
rewound: z52.number(),
|
|
7416
|
+
linesRead: z52.number(),
|
|
7417
|
+
malformedLines: z52.number(),
|
|
7418
|
+
blobs: z52.number(),
|
|
7419
|
+
ingested: z52.number(),
|
|
7420
|
+
newTemplates: z52.number(),
|
|
7421
|
+
templates: z52.number(),
|
|
7422
|
+
evicting: z52.boolean(),
|
|
7423
|
+
curve: z52.array(z52.object({ blobs: z52.number(), templates: z52.number(), evicting: z52.boolean() })),
|
|
7424
|
+
errors: z52.array(z52.string())
|
|
7346
7425
|
});
|
|
7347
7426
|
var miner_drain_ingest_default = defineCommand({
|
|
7348
7427
|
name: "miner.drain-ingest",
|
|
7349
7428
|
description: "Cluster new tool-result/error blobs from Claude transcripts into the template store.",
|
|
7350
|
-
args:
|
|
7351
|
-
result:
|
|
7429
|
+
args: ArgsSchema44,
|
|
7430
|
+
result: ResultSchema40,
|
|
7352
7431
|
cli: {
|
|
7353
7432
|
options: {
|
|
7354
7433
|
full: {
|
|
@@ -7375,52 +7454,52 @@ var miner_drain_ingest_default = defineCommand({
|
|
|
7375
7454
|
});
|
|
7376
7455
|
|
|
7377
7456
|
// src/commands/miner-refresh.ts
|
|
7378
|
-
import { z as
|
|
7379
|
-
var
|
|
7380
|
-
full:
|
|
7381
|
-
limit:
|
|
7382
|
-
verify_hashes:
|
|
7383
|
-
});
|
|
7384
|
-
var WorkspaceSchema =
|
|
7385
|
-
files:
|
|
7386
|
-
indexed:
|
|
7387
|
-
unchanged:
|
|
7388
|
-
removed:
|
|
7389
|
-
malformed:
|
|
7390
|
-
rows:
|
|
7391
|
-
initiative:
|
|
7392
|
-
note:
|
|
7393
|
-
task:
|
|
7394
|
-
session:
|
|
7395
|
-
source:
|
|
7457
|
+
import { z as z53 } from "zod";
|
|
7458
|
+
var ArgsSchema45 = z53.object({
|
|
7459
|
+
full: z53.boolean().optional(),
|
|
7460
|
+
limit: z53.coerce.number().int().positive().optional(),
|
|
7461
|
+
verify_hashes: z53.boolean().optional()
|
|
7462
|
+
});
|
|
7463
|
+
var WorkspaceSchema = z53.object({
|
|
7464
|
+
files: z53.number(),
|
|
7465
|
+
indexed: z53.number(),
|
|
7466
|
+
unchanged: z53.number(),
|
|
7467
|
+
removed: z53.number(),
|
|
7468
|
+
malformed: z53.array(z53.object({ path: z53.string(), reason: z53.string() })),
|
|
7469
|
+
rows: z53.object({
|
|
7470
|
+
initiative: z53.number(),
|
|
7471
|
+
note: z53.number(),
|
|
7472
|
+
task: z53.number(),
|
|
7473
|
+
session: z53.number(),
|
|
7474
|
+
source: z53.number()
|
|
7396
7475
|
}),
|
|
7397
|
-
edges:
|
|
7398
|
-
orphanRatio:
|
|
7476
|
+
edges: z53.object({ holds: z53.number(), mentions: z53.number(), sharesTag: z53.number() }),
|
|
7477
|
+
orphanRatio: z53.number()
|
|
7399
7478
|
});
|
|
7400
|
-
var
|
|
7401
|
-
startedAt:
|
|
7402
|
-
durationMs:
|
|
7403
|
-
transcripts:
|
|
7404
|
-
scanned:
|
|
7405
|
-
indexed:
|
|
7406
|
-
rewound:
|
|
7407
|
-
unchanged:
|
|
7408
|
-
quarantined:
|
|
7409
|
-
missing:
|
|
7410
|
-
reconciledMissing:
|
|
7411
|
-
factsAdded:
|
|
7412
|
-
turnsRolledUp:
|
|
7413
|
-
tasksRequested:
|
|
7414
|
-
tasksApplied:
|
|
7479
|
+
var ResultSchema41 = z53.object({
|
|
7480
|
+
startedAt: z53.string(),
|
|
7481
|
+
durationMs: z53.number(),
|
|
7482
|
+
transcripts: z53.number(),
|
|
7483
|
+
scanned: z53.number(),
|
|
7484
|
+
indexed: z53.number(),
|
|
7485
|
+
rewound: z53.number(),
|
|
7486
|
+
unchanged: z53.number(),
|
|
7487
|
+
quarantined: z53.number(),
|
|
7488
|
+
missing: z53.number(),
|
|
7489
|
+
reconciledMissing: z53.number(),
|
|
7490
|
+
factsAdded: z53.number(),
|
|
7491
|
+
turnsRolledUp: z53.number(),
|
|
7492
|
+
tasksRequested: z53.number(),
|
|
7493
|
+
tasksApplied: z53.number(),
|
|
7415
7494
|
workspace: WorkspaceSchema.nullable(),
|
|
7416
|
-
preserved:
|
|
7417
|
-
errors:
|
|
7495
|
+
preserved: z53.object({ restored: z53.number(), merged: z53.number(), skipped: z53.number() }),
|
|
7496
|
+
errors: z53.array(z53.string())
|
|
7418
7497
|
});
|
|
7419
7498
|
var miner_refresh_default = defineCommand({
|
|
7420
7499
|
name: "miner.refresh",
|
|
7421
7500
|
description: "Index new Claude session transcripts into the session-signal index.",
|
|
7422
|
-
args:
|
|
7423
|
-
result:
|
|
7501
|
+
args: ArgsSchema45,
|
|
7502
|
+
result: ResultSchema41,
|
|
7424
7503
|
cli: {
|
|
7425
7504
|
options: {
|
|
7426
7505
|
full: {
|
|
@@ -7446,7 +7525,7 @@ var miner_refresh_default = defineCommand({
|
|
|
7446
7525
|
|
|
7447
7526
|
// src/commands/miner-liveness.ts
|
|
7448
7527
|
import { existsSync as existsSync3 } from "fs";
|
|
7449
|
-
import { z as
|
|
7528
|
+
import { z as z54 } from "zod";
|
|
7450
7529
|
|
|
7451
7530
|
// src/session-index/liveness.ts
|
|
7452
7531
|
import { existsSync as existsSync2 } from "fs";
|
|
@@ -7563,22 +7642,22 @@ function runLiveness(db) {
|
|
|
7563
7642
|
}
|
|
7564
7643
|
|
|
7565
7644
|
// src/commands/miner-liveness.ts
|
|
7566
|
-
var
|
|
7567
|
-
var
|
|
7568
|
-
emptyColumns:
|
|
7569
|
-
|
|
7645
|
+
var ArgsSchema46 = z54.object({});
|
|
7646
|
+
var ResultSchema42 = z54.object({
|
|
7647
|
+
emptyColumns: z54.array(
|
|
7648
|
+
z54.object({ table: z54.string(), column: z54.string(), rows: z54.number(), nonNull: z54.number() })
|
|
7570
7649
|
),
|
|
7571
|
-
unusedRelations:
|
|
7572
|
-
undeclaredRelations:
|
|
7573
|
-
danglingNamespaces:
|
|
7574
|
-
|
|
7650
|
+
unusedRelations: z54.array(z54.string()),
|
|
7651
|
+
undeclaredRelations: z54.array(z54.string()),
|
|
7652
|
+
danglingNamespaces: z54.array(
|
|
7653
|
+
z54.object({ namespace: z54.string(), edges: z54.number(), dangling: z54.number() })
|
|
7575
7654
|
),
|
|
7576
|
-
unmappedNamespaces:
|
|
7577
|
-
expectedEmptyColumns:
|
|
7578
|
-
|
|
7655
|
+
unmappedNamespaces: z54.array(z54.string()),
|
|
7656
|
+
expectedEmptyColumns: z54.array(
|
|
7657
|
+
z54.object({ table: z54.string(), column: z54.string(), reason: z54.string() })
|
|
7579
7658
|
),
|
|
7580
|
-
staleTranscripts:
|
|
7581
|
-
transcripts:
|
|
7659
|
+
staleTranscripts: z54.number(),
|
|
7660
|
+
transcripts: z54.number()
|
|
7582
7661
|
});
|
|
7583
7662
|
function report(result) {
|
|
7584
7663
|
const lines = [color.bold("active-work miner liveness")];
|
|
@@ -7630,8 +7709,8 @@ function report(result) {
|
|
|
7630
7709
|
var miner_liveness_default = defineCommand({
|
|
7631
7710
|
name: "miner.liveness",
|
|
7632
7711
|
description: "Report which declared index structures nothing ever populates: empty columns, unused edge relations, dangling refs, stale transcripts.",
|
|
7633
|
-
args:
|
|
7634
|
-
result:
|
|
7712
|
+
args: ArgsSchema46,
|
|
7713
|
+
result: ResultSchema42,
|
|
7635
7714
|
cli: { usage: "active-work miner liveness" },
|
|
7636
7715
|
async run(_args, ctx) {
|
|
7637
7716
|
const dbPath = defaultGraphPath();
|
|
@@ -7669,40 +7748,40 @@ var miner_liveness_default = defineCommand({
|
|
|
7669
7748
|
|
|
7670
7749
|
// src/commands/miner-status.ts
|
|
7671
7750
|
import { existsSync as existsSync4, statSync } from "fs";
|
|
7672
|
-
import { z as
|
|
7673
|
-
var
|
|
7674
|
-
var
|
|
7675
|
-
dbPath:
|
|
7676
|
-
schemaVersion:
|
|
7677
|
-
sizeBytes:
|
|
7678
|
-
counts:
|
|
7679
|
-
transcripts:
|
|
7680
|
-
sessions:
|
|
7681
|
-
facts:
|
|
7682
|
-
turns:
|
|
7683
|
-
edges:
|
|
7684
|
-
spans:
|
|
7751
|
+
import { z as z55 } from "zod";
|
|
7752
|
+
var ArgsSchema47 = z55.object({});
|
|
7753
|
+
var ResultSchema43 = z55.object({
|
|
7754
|
+
dbPath: z55.string(),
|
|
7755
|
+
schemaVersion: z55.number(),
|
|
7756
|
+
sizeBytes: z55.number(),
|
|
7757
|
+
counts: z55.object({
|
|
7758
|
+
transcripts: z55.number(),
|
|
7759
|
+
sessions: z55.number(),
|
|
7760
|
+
facts: z55.number(),
|
|
7761
|
+
turns: z55.number(),
|
|
7762
|
+
edges: z55.number(),
|
|
7763
|
+
spans: z55.number()
|
|
7685
7764
|
}),
|
|
7686
|
-
transcripts:
|
|
7687
|
-
ok:
|
|
7688
|
-
quarantined:
|
|
7689
|
-
missing:
|
|
7765
|
+
transcripts: z55.object({
|
|
7766
|
+
ok: z55.number(),
|
|
7767
|
+
quarantined: z55.number(),
|
|
7768
|
+
missing: z55.number()
|
|
7690
7769
|
}),
|
|
7691
|
-
watermark:
|
|
7692
|
-
lastIndexedAt:
|
|
7693
|
-
behindBytes:
|
|
7770
|
+
watermark: z55.object({
|
|
7771
|
+
lastIndexedAt: z55.string().nullable(),
|
|
7772
|
+
behindBytes: z55.number()
|
|
7694
7773
|
}),
|
|
7695
|
-
fts:
|
|
7696
|
-
rows:
|
|
7697
|
-
orphanRows:
|
|
7698
|
-
needsFullRebuild:
|
|
7774
|
+
fts: z55.object({
|
|
7775
|
+
rows: z55.number(),
|
|
7776
|
+
orphanRows: z55.number(),
|
|
7777
|
+
needsFullRebuild: z55.boolean()
|
|
7699
7778
|
}),
|
|
7700
|
-
daemon:
|
|
7701
|
-
indexing:
|
|
7702
|
-
pending:
|
|
7703
|
-
lastRunAt:
|
|
7704
|
-
lastDurationMs:
|
|
7705
|
-
consecutiveErrors:
|
|
7779
|
+
daemon: z55.object({
|
|
7780
|
+
indexing: z55.boolean(),
|
|
7781
|
+
pending: z55.boolean(),
|
|
7782
|
+
lastRunAt: z55.string().nullable(),
|
|
7783
|
+
lastDurationMs: z55.number().nullable(),
|
|
7784
|
+
consecutiveErrors: z55.number()
|
|
7706
7785
|
}).nullable()
|
|
7707
7786
|
});
|
|
7708
7787
|
var ORPHAN_WARN_RATIO = 0.2;
|
|
@@ -7743,8 +7822,8 @@ async function emptyStatus(dbPath) {
|
|
|
7743
7822
|
var miner_status_default = defineCommand({
|
|
7744
7823
|
name: "miner.status",
|
|
7745
7824
|
description: "Report session-signal index size, freshness, and daemon indexing state.",
|
|
7746
|
-
args:
|
|
7747
|
-
result:
|
|
7825
|
+
args: ArgsSchema47,
|
|
7826
|
+
result: ResultSchema43,
|
|
7748
7827
|
async run() {
|
|
7749
7828
|
const dbPath = defaultGraphPath();
|
|
7750
7829
|
if (!existsSync4(dbPath)) return emptyStatus(dbPath);
|
|
@@ -7786,7 +7865,7 @@ var miner_status_default = defineCommand({
|
|
|
7786
7865
|
});
|
|
7787
7866
|
|
|
7788
7867
|
// src/commands/hooks-agent-chat-spawn.ts
|
|
7789
|
-
import { z as
|
|
7868
|
+
import { z as z57 } from "zod";
|
|
7790
7869
|
|
|
7791
7870
|
// src/utils/read-stdin-json.ts
|
|
7792
7871
|
async function readStdinJson(stream = process.stdin) {
|
|
@@ -7807,12 +7886,12 @@ async function readStdinJson(stream = process.stdin) {
|
|
|
7807
7886
|
// src/utils/agent-chat-hook-state.ts
|
|
7808
7887
|
import { promises as fs49 } from "fs";
|
|
7809
7888
|
import path61 from "path";
|
|
7810
|
-
import { z as
|
|
7811
|
-
var SpawnContextSchema =
|
|
7812
|
-
slug:
|
|
7813
|
-
sessionId:
|
|
7814
|
-
name:
|
|
7815
|
-
started:
|
|
7889
|
+
import { z as z56 } from "zod";
|
|
7890
|
+
var SpawnContextSchema = z56.object({
|
|
7891
|
+
slug: z56.string().min(1),
|
|
7892
|
+
sessionId: z56.string().min(1),
|
|
7893
|
+
name: z56.string(),
|
|
7894
|
+
started: z56.string(),
|
|
7816
7895
|
/**
|
|
7817
7896
|
* The spawning session, already resolved from the payload's `parent`
|
|
7818
7897
|
* agentId to a session id. Resolved at spawn time on purpose: `parent` names
|
|
@@ -7820,10 +7899,10 @@ var SpawnContextSchema = z55.object({
|
|
|
7820
7899
|
* another live entry in this same directory — which is gone by the time
|
|
7821
7900
|
* on_complete runs, because reading one deletes it.
|
|
7822
7901
|
*/
|
|
7823
|
-
parentSessionId:
|
|
7902
|
+
parentSessionId: z56.string().min(1).nullable().default(null),
|
|
7824
7903
|
/** agent-chat profile and briefing slug, for the recorded session's prose. */
|
|
7825
|
-
profile:
|
|
7826
|
-
briefing:
|
|
7904
|
+
profile: z56.string().nullable().default(null),
|
|
7905
|
+
briefing: z56.string().nullable().default(null)
|
|
7827
7906
|
});
|
|
7828
7907
|
function stateDir() {
|
|
7829
7908
|
return path61.join(getStateRoot(), "agent-chat-hooks");
|
|
@@ -7855,10 +7934,10 @@ async function peekSpawnContext(agentId) {
|
|
|
7855
7934
|
}
|
|
7856
7935
|
|
|
7857
7936
|
// src/commands/hooks-agent-chat-spawn.ts
|
|
7858
|
-
var
|
|
7859
|
-
var
|
|
7860
|
-
matched:
|
|
7861
|
-
slug:
|
|
7937
|
+
var ArgsSchema48 = z57.object({});
|
|
7938
|
+
var ResultSchema44 = z57.object({
|
|
7939
|
+
matched: z57.boolean(),
|
|
7940
|
+
slug: z57.string().nullable()
|
|
7862
7941
|
});
|
|
7863
7942
|
function str2(source, key) {
|
|
7864
7943
|
const value = source?.[key];
|
|
@@ -7887,8 +7966,8 @@ async function handleOnSpawn(payload, activeRoot) {
|
|
|
7887
7966
|
var hooks_agent_chat_spawn_default = defineCommand({
|
|
7888
7967
|
name: "hooks.agent-chat-spawn",
|
|
7889
7968
|
description: "agent-chat on_spawn hook consumer (AW-99): stash a spawned peer's context, keyed by agentId, for the matching on_complete call.",
|
|
7890
|
-
args:
|
|
7891
|
-
result:
|
|
7969
|
+
args: ArgsSchema48,
|
|
7970
|
+
result: ResultSchema44,
|
|
7892
7971
|
cli: {
|
|
7893
7972
|
usage: "active-work hooks agent-chat-spawn (reads the on_spawn JSON payload from stdin)"
|
|
7894
7973
|
},
|
|
@@ -7900,11 +7979,11 @@ var hooks_agent_chat_spawn_default = defineCommand({
|
|
|
7900
7979
|
|
|
7901
7980
|
// src/commands/hooks-agent-chat-complete.ts
|
|
7902
7981
|
import { spawn as spawn5 } from "child_process";
|
|
7903
|
-
import { z as
|
|
7904
|
-
var
|
|
7905
|
-
var
|
|
7906
|
-
recorded:
|
|
7907
|
-
slug:
|
|
7982
|
+
import { z as z58 } from "zod";
|
|
7983
|
+
var ArgsSchema49 = z58.object({});
|
|
7984
|
+
var ResultSchema45 = z58.object({
|
|
7985
|
+
recorded: z58.boolean(),
|
|
7986
|
+
slug: z58.string().nullable()
|
|
7908
7987
|
});
|
|
7909
7988
|
function str3(source, key) {
|
|
7910
7989
|
const value = source?.[key];
|
|
@@ -7971,8 +8050,8 @@ async function handleOnComplete(payload) {
|
|
|
7971
8050
|
var hooks_agent_chat_complete_default = defineCommand({
|
|
7972
8051
|
name: "hooks.agent-chat-complete",
|
|
7973
8052
|
description: "agent-chat on_complete hook consumer (AW-99): record a spawned peer's run as a track:adhoc session via wrap.",
|
|
7974
|
-
args:
|
|
7975
|
-
result:
|
|
8053
|
+
args: ArgsSchema49,
|
|
8054
|
+
result: ResultSchema45,
|
|
7976
8055
|
cli: {
|
|
7977
8056
|
usage: "active-work hooks agent-chat-complete (reads the on_complete JSON payload from stdin)"
|
|
7978
8057
|
},
|
|
@@ -7983,7 +8062,7 @@ var hooks_agent_chat_complete_default = defineCommand({
|
|
|
7983
8062
|
});
|
|
7984
8063
|
|
|
7985
8064
|
// src/commands/setup.ts
|
|
7986
|
-
import { z as
|
|
8065
|
+
import { z as z60 } from "zod";
|
|
7987
8066
|
|
|
7988
8067
|
// src/setup/steps.ts
|
|
7989
8068
|
import { promises as fsp3, existsSync as existsSync5 } from "fs";
|
|
@@ -8134,7 +8213,7 @@ import path64 from "path";
|
|
|
8134
8213
|
|
|
8135
8214
|
// src/migrations/v3-proposal.ts
|
|
8136
8215
|
import { promises as fs51 } from "fs";
|
|
8137
|
-
import { z as
|
|
8216
|
+
import { z as z59 } from "zod";
|
|
8138
8217
|
|
|
8139
8218
|
// src/migrations/data/v3-open-loops-proposal.ts
|
|
8140
8219
|
var V3_OPEN_LOOPS_PROPOSAL = {
|
|
@@ -8930,36 +9009,36 @@ var KEBAB_SESSION_ID = SessionIdSchema.regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, {
|
|
|
8930
9009
|
message: "session_id must be kebab-case ([a-z0-9-], no leading/trailing dash)"
|
|
8931
9010
|
});
|
|
8932
9011
|
var ISO_INSTANT = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/;
|
|
8933
|
-
var AbandonedSchema =
|
|
9012
|
+
var AbandonedSchema = z59.object({ note: z59.string().min(1) });
|
|
8934
9013
|
var ProposalNextStepSchema = NextStepSchema.extend({
|
|
8935
9014
|
abandoned: AbandonedSchema.optional()
|
|
8936
9015
|
});
|
|
8937
|
-
var ProposalInitiativeSchema =
|
|
8938
|
-
slug:
|
|
9016
|
+
var ProposalInitiativeSchema = z59.object({
|
|
9017
|
+
slug: z59.string().min(1),
|
|
8939
9018
|
/**
|
|
8940
9019
|
* Real last-touch of the initiative, hand-supplied. Never `Date.now()` and
|
|
8941
9020
|
* never file mtime — several initiatives have mtimes months adrift from
|
|
8942
9021
|
* their true last-touch, and the whole point of back-dating is to preserve
|
|
8943
9022
|
* the staleness signal.
|
|
8944
9023
|
*/
|
|
8945
|
-
ended:
|
|
9024
|
+
ended: z59.string().regex(ISO_INSTANT, {
|
|
8946
9025
|
message: "ended must be an ISO 8601 instant with timezone"
|
|
8947
9026
|
}),
|
|
8948
9027
|
session_id: KEBAB_SESSION_ID,
|
|
8949
|
-
body:
|
|
8950
|
-
next_steps:
|
|
9028
|
+
body: z59.string().min(1),
|
|
9029
|
+
next_steps: z59.array(ProposalNextStepSchema).default([])
|
|
8951
9030
|
});
|
|
8952
|
-
var ProposalSchema =
|
|
9031
|
+
var ProposalSchema = z59.object({
|
|
8953
9032
|
/**
|
|
8954
9033
|
* When the abandonment decision was made. Hand-supplied rather than read
|
|
8955
9034
|
* from the clock: the second session's filename derives from it, and the
|
|
8956
9035
|
* migration keys idempotence on exact paths, so `Date.now()` would mint a
|
|
8957
9036
|
* fresh path — and a duplicate abandonment session — on every re-run.
|
|
8958
9037
|
*/
|
|
8959
|
-
abandoned_at:
|
|
9038
|
+
abandoned_at: z59.string().regex(ISO_INSTANT, {
|
|
8960
9039
|
message: "abandoned_at must be an ISO 8601 instant with timezone"
|
|
8961
9040
|
}).optional(),
|
|
8962
|
-
initiatives:
|
|
9041
|
+
initiatives: z59.array(ProposalInitiativeSchema)
|
|
8963
9042
|
}).superRefine((value, ctx) => {
|
|
8964
9043
|
const withAbandoned = value.initiatives.filter(
|
|
8965
9044
|
(i) => i.next_steps.some((n) => n.abandoned !== void 0)
|
|
@@ -9522,12 +9601,12 @@ var v3ToV4Worktrees = {
|
|
|
9522
9601
|
|
|
9523
9602
|
// src/migrations/index.ts
|
|
9524
9603
|
var BASE_VERSION = 1;
|
|
9525
|
-
var
|
|
9526
|
-
var CURRENT_VERSION = targetVersion(
|
|
9604
|
+
var MIGRATIONS = [v1ToV2Artifacts, v2ToV3OpenLoops, v3ToV4Worktrees];
|
|
9605
|
+
var CURRENT_VERSION = targetVersion(MIGRATIONS);
|
|
9527
9606
|
function targetVersion(migrations) {
|
|
9528
9607
|
return migrations.reduce((highest, m) => Math.max(highest, m.to), BASE_VERSION);
|
|
9529
9608
|
}
|
|
9530
|
-
async function
|
|
9609
|
+
async function runMigrations(activeRoot, fromVersion, migrations = MIGRATIONS) {
|
|
9531
9610
|
if (fromVersion === CURRENT_VERSION) {
|
|
9532
9611
|
return { ran: [] };
|
|
9533
9612
|
}
|
|
@@ -9636,7 +9715,7 @@ async function ensureSchemaVersion(activeRoot) {
|
|
|
9636
9715
|
if (before === CURRENT_VERSION) {
|
|
9637
9716
|
return { before, after: before, migrated: false, ran: [] };
|
|
9638
9717
|
}
|
|
9639
|
-
const { ran } = await
|
|
9718
|
+
const { ran } = await runMigrations(activeRoot, before);
|
|
9640
9719
|
await writeSchemaVersion(activeRoot, CURRENT_VERSION);
|
|
9641
9720
|
return {
|
|
9642
9721
|
before,
|
|
@@ -10889,20 +10968,20 @@ async function runUninstall(deps = {}) {
|
|
|
10889
10968
|
}
|
|
10890
10969
|
|
|
10891
10970
|
// src/commands/setup.ts
|
|
10892
|
-
var
|
|
10893
|
-
update:
|
|
10894
|
-
yes:
|
|
10971
|
+
var ArgsSchema50 = z60.object({
|
|
10972
|
+
update: z60.boolean().optional(),
|
|
10973
|
+
yes: z60.boolean().optional()
|
|
10895
10974
|
});
|
|
10896
|
-
var StepSchema =
|
|
10897
|
-
name:
|
|
10898
|
-
ok:
|
|
10899
|
-
done:
|
|
10900
|
-
message:
|
|
10901
|
-
error:
|
|
10975
|
+
var StepSchema = z60.object({
|
|
10976
|
+
name: z60.string(),
|
|
10977
|
+
ok: z60.boolean(),
|
|
10978
|
+
done: z60.boolean().optional(),
|
|
10979
|
+
message: z60.string().optional(),
|
|
10980
|
+
error: z60.string().optional()
|
|
10902
10981
|
});
|
|
10903
|
-
var
|
|
10904
|
-
banner:
|
|
10905
|
-
steps:
|
|
10982
|
+
var ResultSchema46 = z60.object({
|
|
10983
|
+
banner: z60.string(),
|
|
10984
|
+
steps: z60.array(StepSchema)
|
|
10906
10985
|
});
|
|
10907
10986
|
function printStep(step) {
|
|
10908
10987
|
if (step.ok) {
|
|
@@ -10919,8 +10998,8 @@ function printStep(step) {
|
|
|
10919
10998
|
var setup_default = defineCommand({
|
|
10920
10999
|
name: "setup",
|
|
10921
11000
|
description: "Interactive wizard: verifies Node, scaffolds directories, registers the MCP server, and optionally starts the daemon and walks through ingestion.",
|
|
10922
|
-
args:
|
|
10923
|
-
result:
|
|
11001
|
+
args: ArgsSchema50,
|
|
11002
|
+
result: ResultSchema46,
|
|
10924
11003
|
cli: {
|
|
10925
11004
|
options: {
|
|
10926
11005
|
update: {
|
|
@@ -10955,25 +11034,25 @@ var setup_default = defineCommand({
|
|
|
10955
11034
|
});
|
|
10956
11035
|
|
|
10957
11036
|
// src/commands/uninstall.ts
|
|
10958
|
-
import { z as
|
|
10959
|
-
var
|
|
10960
|
-
yes:
|
|
11037
|
+
import { z as z61 } from "zod";
|
|
11038
|
+
var ArgsSchema51 = z61.object({
|
|
11039
|
+
yes: z61.boolean().optional()
|
|
10961
11040
|
});
|
|
10962
|
-
var StepSchema2 =
|
|
10963
|
-
name:
|
|
10964
|
-
done:
|
|
10965
|
-
message:
|
|
10966
|
-
error:
|
|
11041
|
+
var StepSchema2 = z61.object({
|
|
11042
|
+
name: z61.string(),
|
|
11043
|
+
done: z61.boolean(),
|
|
11044
|
+
message: z61.string().optional(),
|
|
11045
|
+
error: z61.string().optional()
|
|
10967
11046
|
});
|
|
10968
|
-
var
|
|
10969
|
-
steps:
|
|
10970
|
-
activeRootPreservedAt:
|
|
11047
|
+
var ResultSchema47 = z61.object({
|
|
11048
|
+
steps: z61.array(StepSchema2),
|
|
11049
|
+
activeRootPreservedAt: z61.string()
|
|
10971
11050
|
});
|
|
10972
11051
|
var uninstall_default = defineCommand({
|
|
10973
11052
|
name: "uninstall",
|
|
10974
11053
|
description: "Reverse what setup did: remove the skill, stop the daemon, unregister MCP. Preserves the active root.",
|
|
10975
|
-
args:
|
|
10976
|
-
result:
|
|
11054
|
+
args: ArgsSchema51,
|
|
11055
|
+
result: ResultSchema47,
|
|
10977
11056
|
cli: {
|
|
10978
11057
|
options: {
|
|
10979
11058
|
yes: {
|
|
@@ -11003,7 +11082,7 @@ var uninstall_default = defineCommand({
|
|
|
11003
11082
|
});
|
|
11004
11083
|
|
|
11005
11084
|
// src/commands/doctor.ts
|
|
11006
|
-
import { z as
|
|
11085
|
+
import { z as z62 } from "zod";
|
|
11007
11086
|
|
|
11008
11087
|
// src/doctor.ts
|
|
11009
11088
|
import { promises as fsp4 } from "fs";
|
|
@@ -11411,15 +11490,15 @@ async function runDoctor(deps = {}) {
|
|
|
11411
11490
|
}
|
|
11412
11491
|
|
|
11413
11492
|
// src/commands/doctor.ts
|
|
11414
|
-
var
|
|
11415
|
-
var CheckSchema =
|
|
11416
|
-
name:
|
|
11417
|
-
status:
|
|
11418
|
-
detail:
|
|
11493
|
+
var ArgsSchema52 = z62.object({});
|
|
11494
|
+
var CheckSchema = z62.object({
|
|
11495
|
+
name: z62.string(),
|
|
11496
|
+
status: z62.enum(["ok", "warn", "fail"]),
|
|
11497
|
+
detail: z62.string()
|
|
11419
11498
|
});
|
|
11420
|
-
var
|
|
11421
|
-
ok:
|
|
11422
|
-
checks:
|
|
11499
|
+
var ResultSchema48 = z62.object({
|
|
11500
|
+
ok: z62.boolean(),
|
|
11501
|
+
checks: z62.array(CheckSchema)
|
|
11423
11502
|
});
|
|
11424
11503
|
function badge(status) {
|
|
11425
11504
|
if (status === "ok") return color.green("OK ");
|
|
@@ -11429,8 +11508,8 @@ function badge(status) {
|
|
|
11429
11508
|
var doctor_default = defineCommand({
|
|
11430
11509
|
name: "doctor",
|
|
11431
11510
|
description: "Health-check the install: Node, active root, daemon, MCP registration, skill, and supervision.",
|
|
11432
|
-
args:
|
|
11433
|
-
result:
|
|
11511
|
+
args: ArgsSchema52,
|
|
11512
|
+
result: ResultSchema48,
|
|
11434
11513
|
async run(_args, ctx) {
|
|
11435
11514
|
const report2 = await runDoctor();
|
|
11436
11515
|
if (ctx.format !== "json") {
|
|
@@ -11447,34 +11526,34 @@ var doctor_default = defineCommand({
|
|
|
11447
11526
|
});
|
|
11448
11527
|
|
|
11449
11528
|
// src/commands/migrate.ts
|
|
11450
|
-
import { z as
|
|
11451
|
-
var
|
|
11452
|
-
dry_run:
|
|
11453
|
-
apply:
|
|
11454
|
-
});
|
|
11455
|
-
var SessionSchema =
|
|
11456
|
-
kind:
|
|
11457
|
-
action:
|
|
11458
|
-
file:
|
|
11459
|
-
ended:
|
|
11460
|
-
loops:
|
|
11461
|
-
resolves:
|
|
11462
|
-
});
|
|
11463
|
-
var InitiativeSchema =
|
|
11464
|
-
slug:
|
|
11465
|
-
sessions:
|
|
11466
|
-
task_seq_backfill:
|
|
11467
|
-
brief_repairs:
|
|
11468
|
-
brief_blocked:
|
|
11469
|
-
handoff:
|
|
11470
|
-
note:
|
|
11529
|
+
import { z as z63 } from "zod";
|
|
11530
|
+
var ArgsSchema53 = z63.object({
|
|
11531
|
+
dry_run: z63.boolean().optional(),
|
|
11532
|
+
apply: z63.boolean().optional()
|
|
11533
|
+
});
|
|
11534
|
+
var SessionSchema = z63.object({
|
|
11535
|
+
kind: z63.enum(["open", "abandon"]),
|
|
11536
|
+
action: z63.enum(["write", "exists"]),
|
|
11537
|
+
file: z63.string(),
|
|
11538
|
+
ended: z63.string(),
|
|
11539
|
+
loops: z63.number().int().nonnegative(),
|
|
11540
|
+
resolves: z63.number().int().nonnegative()
|
|
11541
|
+
});
|
|
11542
|
+
var InitiativeSchema = z63.object({
|
|
11543
|
+
slug: z63.string(),
|
|
11544
|
+
sessions: z63.array(SessionSchema),
|
|
11545
|
+
task_seq_backfill: z63.number().int().positive().nullable(),
|
|
11546
|
+
brief_repairs: z63.array(z63.string()),
|
|
11547
|
+
brief_blocked: z63.string().optional(),
|
|
11548
|
+
handoff: z63.enum(["archive-and-remove", "archive-exists", "absent"]),
|
|
11549
|
+
note: z63.string().optional()
|
|
11471
11550
|
});
|
|
11472
|
-
var
|
|
11473
|
-
applied:
|
|
11474
|
-
proposal:
|
|
11475
|
-
initiatives:
|
|
11476
|
-
repairs:
|
|
11477
|
-
uncovered:
|
|
11551
|
+
var ResultSchema49 = z63.object({
|
|
11552
|
+
applied: z63.boolean(),
|
|
11553
|
+
proposal: z63.string(),
|
|
11554
|
+
initiatives: z63.array(InitiativeSchema),
|
|
11555
|
+
repairs: z63.array(z63.object({ action: z63.string(), file: z63.string(), detail: z63.string() })),
|
|
11556
|
+
uncovered: z63.array(z63.string())
|
|
11478
11557
|
});
|
|
11479
11558
|
function describe2(plan, applied) {
|
|
11480
11559
|
const initiatives = plan.initiatives.map((i) => ({
|
|
@@ -11550,8 +11629,8 @@ function render(result) {
|
|
|
11550
11629
|
var migrate_default = defineCommand({
|
|
11551
11630
|
name: "migrate",
|
|
11552
11631
|
description: "Preview (or apply) the pending v2\u2192v3 open-loops migration.",
|
|
11553
|
-
args:
|
|
11554
|
-
result:
|
|
11632
|
+
args: ArgsSchema53,
|
|
11633
|
+
result: ResultSchema49,
|
|
11555
11634
|
cli: {
|
|
11556
11635
|
options: {
|
|
11557
11636
|
dry_run: { long: "--dry-run", description: "Report what would change; write nothing" },
|
|
@@ -11586,18 +11665,18 @@ var migrate_default = defineCommand({
|
|
|
11586
11665
|
|
|
11587
11666
|
// src/commands/sync.ts
|
|
11588
11667
|
import os7 from "os";
|
|
11589
|
-
import { z as
|
|
11590
|
-
var
|
|
11591
|
-
message:
|
|
11592
|
-
require_clean:
|
|
11593
|
-
});
|
|
11594
|
-
var
|
|
11595
|
-
branch:
|
|
11596
|
-
committed:
|
|
11597
|
-
committed_files:
|
|
11598
|
-
rebased:
|
|
11599
|
-
pushed:
|
|
11600
|
-
summary:
|
|
11668
|
+
import { z as z64 } from "zod";
|
|
11669
|
+
var ArgsSchema54 = z64.object({
|
|
11670
|
+
message: z64.string().min(1).optional(),
|
|
11671
|
+
require_clean: z64.boolean().optional()
|
|
11672
|
+
});
|
|
11673
|
+
var ResultSchema50 = z64.object({
|
|
11674
|
+
branch: z64.string(),
|
|
11675
|
+
committed: z64.boolean(),
|
|
11676
|
+
committed_files: z64.number().int(),
|
|
11677
|
+
rebased: z64.boolean(),
|
|
11678
|
+
pushed: z64.boolean(),
|
|
11679
|
+
summary: z64.string()
|
|
11601
11680
|
});
|
|
11602
11681
|
async function git(root, args) {
|
|
11603
11682
|
return getGitRunner()("git", ["-C", root, ...args]);
|
|
@@ -11699,8 +11778,8 @@ async function push(root) {
|
|
|
11699
11778
|
var sync_default = defineCommand({
|
|
11700
11779
|
name: "sync",
|
|
11701
11780
|
description: "Sync the active root over git: auto-commit local edits, pull --rebase, then push.",
|
|
11702
|
-
args:
|
|
11703
|
-
result:
|
|
11781
|
+
args: ArgsSchema54,
|
|
11782
|
+
result: ResultSchema50,
|
|
11704
11783
|
cli: {
|
|
11705
11784
|
options: {
|
|
11706
11785
|
message: {
|
|
@@ -11794,6 +11873,7 @@ var ALL_COMMANDS = [
|
|
|
11794
11873
|
audit_default,
|
|
11795
11874
|
list_default,
|
|
11796
11875
|
context_graph_default,
|
|
11876
|
+
search_default,
|
|
11797
11877
|
// discover / triage
|
|
11798
11878
|
discover_default,
|
|
11799
11879
|
fold_default,
|