@mmerterden/multi-agent-pipeline 20.28.0 → 20.30.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/CHANGELOG.md +19 -0
- package/README.md +19 -6
- package/README.tr.md +5 -5
- package/docs/architecture.md +3 -3
- package/docs/ecosystem.md +5 -5
- package/docs/facts.json +7 -7
- package/install/catalog-history.json +1 -1
- package/install/claude.mjs +122 -1
- package/install/codex.mjs +2 -0
- package/install/copilot.mjs +13 -0
- package/install/templates/claude-hooks.json +30 -1
- package/manifest.json +189 -77
- package/package.json +2 -1
- package/pipeline/commands/multi-agent/analysis/SKILL.md +3 -1
- package/pipeline/commands/multi-agent/autopilot-on/SKILL.md +13 -15
- package/pipeline/commands/multi-agent/office-off/SKILL.md +27 -0
- package/pipeline/commands/multi-agent/office-on/SKILL.md +50 -0
- package/pipeline/commands/multi-agent/office-status/SKILL.md +29 -0
- package/pipeline/commands/multi-agent/resume/SKILL.md +2 -1
- package/pipeline/commands/multi-agent/serve/SKILL.md +4 -2
- package/pipeline/commands/multi-agent/stack/SKILL.md +15 -8
- package/pipeline/commands/multi-agent/steer/SKILL.md +10 -9
- package/pipeline/commands/multi-agent/sync/SKILL.md +3 -3
- package/pipeline/contract/CHANGELOG.md +62 -0
- package/pipeline/contract/README.md +52 -6
- package/pipeline/contract/fixtures/error-invalid-request.json +1 -1
- package/pipeline/contract/fixtures/error-unauthorized.json +1 -1
- package/pipeline/contract/fixtures/error-unsigned.json +1 -1
- package/pipeline/contract/manifest.json +367 -22
- package/pipeline/contract/types/index.d.ts +531 -4
- package/pipeline/lib/hook-registration.mjs +252 -0
- package/pipeline/lib/prefs-value.mjs +44 -0
- package/pipeline/lib/run-completion.mjs +148 -0
- package/pipeline/multi-agent-refs/analysis/render.md +4 -4
- package/pipeline/multi-agent-refs/cross-cli-contract.md +5 -4
- package/pipeline/multi-agent-refs/features/doctor.md +11 -0
- package/pipeline/multi-agent-refs/features/office-threat-model.md +91 -0
- package/pipeline/multi-agent-refs/help/en.md +3 -0
- package/pipeline/multi-agent-refs/help/tr.md +3 -0
- package/pipeline/multi-agent-refs/phases/operations.md +17 -0
- package/pipeline/multi-agent-refs/phases/phase-0-init.md +6 -2
- package/pipeline/multi-agent-refs/phases/phase-1-plan.md +2 -2
- package/pipeline/multi-agent-refs/phases/phase-2-dev.md +1 -1
- package/pipeline/multi-agent-refs/phases/phase-3-review.md +2 -2
- package/pipeline/multi-agent-refs/phases/phase-4-commit.md +7 -6
- package/pipeline/multi-agent-refs/phases/phase-5-report.md +5 -4
- package/pipeline/office/NOTICE.md +42 -0
- package/pipeline/office/assets/BIN.png +0 -0
- package/pipeline/office/assets/BOOKSHELF.png +0 -0
- package/pipeline/office/assets/CACTUS.png +0 -0
- package/pipeline/office/assets/CLOCK.png +0 -0
- package/pipeline/office/assets/COFFEE.png +0 -0
- package/pipeline/office/assets/COFFEE_TABLE.png +0 -0
- package/pipeline/office/assets/CUSHIONED_BENCH.png +0 -0
- package/pipeline/office/assets/CUSHIONED_CHAIR_BACK.png +0 -0
- package/pipeline/office/assets/CUSHIONED_CHAIR_FRONT.png +0 -0
- package/pipeline/office/assets/CUSHIONED_CHAIR_SIDE.png +0 -0
- package/pipeline/office/assets/DESK_FRONT.png +0 -0
- package/pipeline/office/assets/DESK_SIDE.png +0 -0
- package/pipeline/office/assets/DOUBLE_BOOKSHELF.png +0 -0
- package/pipeline/office/assets/HANGING_PLANT.png +0 -0
- package/pipeline/office/assets/LARGE_PAINTING.png +0 -0
- package/pipeline/office/assets/LARGE_PLANT.png +0 -0
- package/pipeline/office/assets/PC_BACK.png +0 -0
- package/pipeline/office/assets/PC_FRONT_OFF.png +0 -0
- package/pipeline/office/assets/PC_FRONT_ON_1.png +0 -0
- package/pipeline/office/assets/PC_FRONT_ON_2.png +0 -0
- package/pipeline/office/assets/PC_FRONT_ON_3.png +0 -0
- package/pipeline/office/assets/PC_SIDE.png +0 -0
- package/pipeline/office/assets/PLANT.png +0 -0
- package/pipeline/office/assets/PLANT_2.png +0 -0
- package/pipeline/office/assets/POT.png +0 -0
- package/pipeline/office/assets/SMALL_PAINTING.png +0 -0
- package/pipeline/office/assets/SMALL_PAINTING_2.png +0 -0
- package/pipeline/office/assets/SMALL_TABLE_FRONT.png +0 -0
- package/pipeline/office/assets/SMALL_TABLE_SIDE.png +0 -0
- package/pipeline/office/assets/SOFA_BACK.png +0 -0
- package/pipeline/office/assets/SOFA_FRONT.png +0 -0
- package/pipeline/office/assets/SOFA_SIDE.png +0 -0
- package/pipeline/office/assets/TABLE_FRONT.png +0 -0
- package/pipeline/office/assets/WHITEBOARD.png +0 -0
- package/pipeline/office/assets/WOODEN_BENCH.png +0 -0
- package/pipeline/office/assets/WOODEN_CHAIR_BACK.png +0 -0
- package/pipeline/office/assets/WOODEN_CHAIR_FRONT.png +0 -0
- package/pipeline/office/assets/WOODEN_CHAIR_SIDE.png +0 -0
- package/pipeline/office/assets/char_0.png +0 -0
- package/pipeline/office/assets/char_1.png +0 -0
- package/pipeline/office/assets/char_2.png +0 -0
- package/pipeline/office/assets/char_3.png +0 -0
- package/pipeline/office/assets/char_4.png +0 -0
- package/pipeline/office/assets/char_5.png +0 -0
- package/pipeline/office/assets/floor_0.png +0 -0
- package/pipeline/office/assets/floor_1.png +0 -0
- package/pipeline/office/assets/floor_2.png +0 -0
- package/pipeline/office/assets/floor_3.png +0 -0
- package/pipeline/office/assets/floor_4.png +0 -0
- package/pipeline/office/assets/floor_5.png +0 -0
- package/pipeline/office/assets/floor_6.png +0 -0
- package/pipeline/office/assets/floor_7.png +0 -0
- package/pipeline/office/assets/floor_8.png +0 -0
- package/pipeline/office/assets/wall_0.png +0 -0
- package/pipeline/office/index.html +5319 -0
- package/pipeline/preferences-template.json +7 -0
- package/pipeline/rules/figma-pipeline.md +2 -0
- package/pipeline/schemas/activity-chat.schema.json +78 -0
- package/pipeline/schemas/activity-roles.json +48 -0
- package/pipeline/schemas/activity-roles.schema.json +49 -0
- package/pipeline/schemas/activity.schema.json +429 -0
- package/pipeline/schemas/agent-state.schema.json +20 -5
- package/pipeline/schemas/autopilot-on-request.schema.json +33 -0
- package/pipeline/schemas/autopilot-on.schema.json +111 -0
- package/pipeline/schemas/contract-error.schema.json +33 -3
- package/pipeline/schemas/issue-maturity.schema.json +68 -0
- package/pipeline/schemas/ledger.schema.json +202 -0
- package/pipeline/schemas/permissions.schema.json +47 -0
- package/pipeline/schemas/phases.json +3 -2
- package/pipeline/schemas/phases.schema.json +5 -1
- package/pipeline/schemas/prefs.schema.json +56 -0
- package/pipeline/schemas/prs.schema.json +73 -0
- package/pipeline/schemas/review-verdict-request.schema.json +20 -0
- package/pipeline/schemas/review-verdict.schema.json +62 -0
- package/pipeline/schemas/routine-delete.schema.json +59 -0
- package/pipeline/schemas/routines.schema.json +38 -0
- package/pipeline/schemas/run-evidence.schema.json +29 -0
- package/pipeline/schemas/run-results.schema.json +218 -0
- package/pipeline/schemas/runs-index.schema.json +1 -1
- package/pipeline/schemas/service-read.schema.json +58 -0
- package/pipeline/schemas/stack-change.schema.json +82 -0
- package/pipeline/schemas/stack-request.schema.json +33 -0
- package/pipeline/schemas/stack.schema.json +59 -0
- package/pipeline/schemas/steer-request.schema.json +25 -0
- package/pipeline/schemas/steer.schema.json +59 -0
- package/pipeline/schemas/tool-call-request.schema.json +19 -0
- package/pipeline/schemas/tool-call.schema.json +47 -0
- package/pipeline/schemas/tools.schema.json +60 -0
- package/pipeline/scripts/_active-run.mjs +158 -0
- package/pipeline/scripts/_autopilot-outcomes.mjs +1 -0
- package/pipeline/scripts/_cost.mjs +66 -1
- package/pipeline/scripts/_guard_rules.py +605 -0
- package/pipeline/scripts/_office-smoke-lib.sh +115 -0
- package/pipeline/scripts/_spawn-async.mjs +73 -0
- package/pipeline/scripts/_transcript-tail.mjs +274 -0
- package/pipeline/scripts/activity-snapshot.mjs +1027 -0
- package/pipeline/scripts/agent-guard.py +118 -7
- package/pipeline/scripts/agent-guard.sh +50 -3
- package/pipeline/scripts/argv-secret-scan.mjs +114 -0
- package/pipeline/scripts/autopilot-control.mjs +214 -9
- package/pipeline/scripts/autopilot-runner.mjs +8 -2
- package/pipeline/scripts/confirm-command.mjs +70 -0
- package/pipeline/scripts/contract-server.mjs +1178 -48
- package/pipeline/scripts/cost-analyze.mjs +2 -53
- package/pipeline/scripts/cost-table.json +1 -0
- package/pipeline/scripts/doctor.mjs +54 -0
- package/pipeline/scripts/evidence-gate.mjs +8 -4
- package/pipeline/scripts/gate-ledger.mjs +163 -7
- package/pipeline/scripts/office-build.mjs +89 -0
- package/pipeline/scripts/office-control.mjs +383 -0
- package/pipeline/scripts/office-ledger.mjs +409 -0
- package/pipeline/scripts/plan-coverage-gate.mjs +9 -8
- package/pipeline/scripts/pre-commit-check.sh +12 -0
- package/pipeline/scripts/routine-registry.mjs +42 -6
- package/pipeline/scripts/run-results.mjs +373 -0
- package/pipeline/scripts/run-scope-guard.mjs +188 -0
- package/pipeline/scripts/run-scope-guard.sh +23 -0
- package/pipeline/scripts/run-stop-guard.mjs +246 -0
- package/pipeline/scripts/run-stop-guard.sh +25 -0
- package/pipeline/scripts/service-read.mjs +244 -0
- package/pipeline/scripts/stack-toggle.mjs +285 -0
- package/pipeline/scripts/steer-run.mjs +97 -0
- package/pipeline/scripts/toolkit-tools.mjs +599 -0
- package/pipeline/scripts/uninstall.mjs +4 -0
- package/pipeline/scripts/validate-state.mjs +26 -0
- package/pipeline/scripts/work-items.mjs +304 -0
- package/pipeline/scripts/write-state.mjs +114 -0
- package/pipeline/skills/.skill-manifest.json +19 -7
- package/pipeline/skills/.skills-index.json +34 -1
- package/pipeline/skills/shared/README.md +6 -3
- package/pipeline/skills/shared/core/multi-agent-autopilot-on/SKILL.md +13 -15
- package/pipeline/skills/shared/core/multi-agent-office-off/SKILL.md +16 -0
- package/pipeline/skills/shared/core/multi-agent-office-on/SKILL.md +22 -0
- package/pipeline/skills/shared/core/multi-agent-office-status/SKILL.md +17 -0
- package/pipeline/skills/shared/core/multi-agent-serve/SKILL.md +4 -2
- package/pipeline/skills/shared/core/multi-agent-stack/SKILL.md +14 -6
- package/pipeline/skills/shared/core/multi-agent-steer/SKILL.md +10 -9
- package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +3 -3
- package/pipeline/skills/skills-index.md +4 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// Generated by pipeline/contract/build.mjs from pipeline/schemas/*.schema.json.
|
|
2
2
|
// Do not edit: change the schema and run `node pipeline/contract/build.mjs --write`.
|
|
3
3
|
|
|
4
|
-
export type ContractVersion = "1.
|
|
5
|
-
export type SurfaceId = "runs" | "run" | "commands" | "questions" | "issues" | "worktrees" | "launch-spec" | "repos" | "launch" | "answer" | "run-log" | "resume" | "kill" | "gc" | "autopilot" | "autopilot-off" | "phone-runs" | "phone-run" | "phone-answer" | "phone-launch";
|
|
4
|
+
export type ContractVersion = "1.4.0";
|
|
5
|
+
export type SurfaceId = "runs" | "run" | "commands" | "questions" | "issues" | "worktrees" | "launch-spec" | "repos" | "launch" | "answer" | "run-log" | "resume" | "kill" | "gc" | "autopilot" | "autopilot-off" | "phone-runs" | "phone-run" | "phone-answer" | "phone-launch" | "autopilot-on" | "steer" | "activity" | "activity-stream" | "agent-chat" | "routines" | "routine-delete" | "stack" | "stack-set" | "ledger" | "run-results" | "run-evidence" | "review-verdict" | "issue-maturity" | "prs" | "tools" | "tool-call" | "service-confluence" | "service-crashlytics" | "service-figma" | "permissions";
|
|
6
6
|
|
|
7
7
|
/** What `runs-index.mjs --json` prints: every run under the log root and the unattended log root (one record per task id), grouped per status/SKILL.md 3b. Fields are only ever added - a decoder ignores keys it does not know. `--redact` drops every x-sensitivity local field (and `logsRoot`) and scrubs the free text in the title, `now`, sub-step names, task subjects and the pending question. */
|
|
8
8
|
export interface RunsIndex {
|
|
@@ -38,7 +38,7 @@ export interface RunsIndexRun {
|
|
|
38
38
|
rev: number | null;
|
|
39
39
|
/** The session id the run was launched under (agent-state sessionId). A client that launched a run through launch.json finds it by this id. Added in 1.1.0. */
|
|
40
40
|
sessionId?: string | null;
|
|
41
|
-
/** The step a paused run re-enters (agent-state waitingFor): maturity, user-channels-choice or question. Added in 1.1.0. */
|
|
41
|
+
/** The step a paused run re-enters (agent-state waitingFor): maturity, user-channels-choice, local-test, attended-reply or question; null or absent when the run is not waiting. Added in 1.1.0. */
|
|
42
42
|
waitingFor?: string | null;
|
|
43
43
|
/** The question the run stopped on, present only with waitingFor question. Answer it with one of options[].id through `answer-question.mjs` or POST /v1/runs/{id}/answer. text and labels are scrubbed under --redact. Added in 1.1.0. */
|
|
44
44
|
pendingQuestion?: null | RunsIndexQuestion;
|
|
@@ -500,10 +500,537 @@ export interface Repos {
|
|
|
500
500
|
}>;
|
|
501
501
|
}
|
|
502
502
|
|
|
503
|
+
/** What GET /v1/activity returns and `activity-snapshot.mjs --json` prints, and what each GET /v1/activity/stream event carries: one room per repository, one table per run (its team; a session no run claims sits at a table of its own), one seat per agent seen in the recent window, the orchestrator at the head. Derived from disk on every call. No field is machine-local: there are no paths, seat labels come from allow-listed fields only (tool name, file basename, sidecar description), and every free-text string has been through the redactor, so the redacted and the full view are the same document. */
|
|
504
|
+
export interface Activity {
|
|
505
|
+
contractVersion: string;
|
|
506
|
+
generatedAt: string;
|
|
507
|
+
/** A session or subagent whose transcript changed within this window has a desk. */
|
|
508
|
+
recentMinutes: number;
|
|
509
|
+
counts: {
|
|
510
|
+
rooms: number;
|
|
511
|
+
tables: number;
|
|
512
|
+
seats: number;
|
|
513
|
+
live: number;
|
|
514
|
+
waiting: number;
|
|
515
|
+
};
|
|
516
|
+
rooms: Array<{
|
|
517
|
+
repo: string;
|
|
518
|
+
tables: Array<ActivityTable>;
|
|
519
|
+
}>;
|
|
520
|
+
/** Runs over more than one repository: the table and the rooms its corridor joins. */
|
|
521
|
+
corridors: Array<{
|
|
522
|
+
tableId: string;
|
|
523
|
+
repos: Array<string>;
|
|
524
|
+
}>;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
export interface ActivityTable {
|
|
528
|
+
id: string;
|
|
529
|
+
/** run: a pipeline run; session: a session no run claims (outside the pipeline); unmatched: a session more than one run could claim, kept apart rather than guessed. */
|
|
530
|
+
kind: "run" | "session" | "unmatched";
|
|
531
|
+
taskId: string | null;
|
|
532
|
+
title: string | null;
|
|
533
|
+
host: "claude" | "copilot" | "codex";
|
|
534
|
+
/** true for a Copilot CLI or Codex session: no subagent detail exists there. */
|
|
535
|
+
limited: boolean;
|
|
536
|
+
sessionId: string | null;
|
|
537
|
+
/** How the session was tied to the run: the session id the run recorded, or its working directory and branch. */
|
|
538
|
+
matchedBy: "session" | "cwd-branch" | null;
|
|
539
|
+
repos: Array<string>;
|
|
540
|
+
phase: {
|
|
541
|
+
id: number;
|
|
542
|
+
name: string;
|
|
543
|
+
/** The last phase id, for an n of last display. */
|
|
544
|
+
last: number;
|
|
545
|
+
} | null;
|
|
546
|
+
now: string | null;
|
|
547
|
+
status: string | null;
|
|
548
|
+
waitingForYou: boolean;
|
|
549
|
+
pendingQuestion: {
|
|
550
|
+
id: string;
|
|
551
|
+
text: string;
|
|
552
|
+
kind: "single-select" | "multi-select";
|
|
553
|
+
options: Array<{
|
|
554
|
+
id: string;
|
|
555
|
+
label: string;
|
|
556
|
+
}>;
|
|
557
|
+
} | null;
|
|
558
|
+
tokens: {
|
|
559
|
+
in: number;
|
|
560
|
+
out: number;
|
|
561
|
+
cached: number;
|
|
562
|
+
} | null;
|
|
563
|
+
estUsd: number | null;
|
|
564
|
+
/** Where tokens and estUsd come from. not-measured means the numbers are null, never 0. */
|
|
565
|
+
costSource: "tracker-state" | "not-measured";
|
|
566
|
+
/** The room this table stands in. */
|
|
567
|
+
repo: string;
|
|
568
|
+
/** worktree: the run works in its own worktree; local: in the main checkout; unknown when the state does not say. */
|
|
569
|
+
location: "worktree" | "local" | "unknown";
|
|
570
|
+
branch: string | null;
|
|
571
|
+
phaseHistory: Array<{
|
|
572
|
+
id: number | null;
|
|
573
|
+
name: string;
|
|
574
|
+
status: string;
|
|
575
|
+
startedAt: string | null;
|
|
576
|
+
completedAt: string | null;
|
|
577
|
+
}>;
|
|
578
|
+
startedAt: string | null;
|
|
579
|
+
elapsedSeconds: number | null;
|
|
580
|
+
/** The seat id that holds the work now. */
|
|
581
|
+
holder: string | null;
|
|
582
|
+
/** The last seat of an earlier phase, for drawing the handoff. */
|
|
583
|
+
previousHolder: string | null;
|
|
584
|
+
seats: Array<ActivitySeat>;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
export interface ActivitySeat {
|
|
588
|
+
id: string;
|
|
589
|
+
sessionId: string | null;
|
|
590
|
+
/** null for the session's own (orchestrator) desk. */
|
|
591
|
+
agentId: string | null;
|
|
592
|
+
agentType: string | null;
|
|
593
|
+
role: string;
|
|
594
|
+
/** The role, numbered when agents of the same role sit at one table (Reviewer 1, Reviewer 2). */
|
|
595
|
+
label: string;
|
|
596
|
+
/** false when the agent type is in no role table entry and the raw type is shown. */
|
|
597
|
+
known: boolean;
|
|
598
|
+
sprite: number;
|
|
599
|
+
color: string;
|
|
600
|
+
model: string | null;
|
|
601
|
+
modelLabel: string | null;
|
|
602
|
+
description: string | null;
|
|
603
|
+
state: "reading" | "writing" | "spawning" | "waiting" | "idle" | "done";
|
|
604
|
+
tool: string | null;
|
|
605
|
+
detail: string | null;
|
|
606
|
+
/** Whether the session is alive per `claude agents --json`; null when that list cannot be read. */
|
|
607
|
+
live: boolean | null;
|
|
608
|
+
startedAt: string | null;
|
|
609
|
+
lastAt: string | null;
|
|
610
|
+
/** The run phase the agent was spawned in; null for the orchestrator or outside a run. */
|
|
611
|
+
phase: number | null;
|
|
612
|
+
status: "working" | "idle" | "done";
|
|
613
|
+
/** What the seat is doing in a few plain words (Reading Foo.swift, Running a command), else the raw tool name. */
|
|
614
|
+
doing: string;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
/** What GET /v1/agents/{sessionId}/{agentId}/chat returns and `activity-snapshot.mjs chat` prints: one page of an agent's transcript read from its end, oldest first, at most `limit` messages. Only user and assistant records are read; api-request records are never parsed and thinking blocks are never emitted. Every text has been through the redactor; a text the outbound gate still flags is replaced by a marker. `before` is the byte offset to send back for the previous page, null at the start of the file. */
|
|
618
|
+
export interface ActivityChat {
|
|
619
|
+
contractVersion: string;
|
|
620
|
+
sessionId: string;
|
|
621
|
+
/** null for the session's own transcript (the orchestrator). */
|
|
622
|
+
agentId: string | null;
|
|
623
|
+
messages: Array<{
|
|
624
|
+
offset: number;
|
|
625
|
+
role: "user" | "assistant";
|
|
626
|
+
at: string | null;
|
|
627
|
+
blocks: Array<{
|
|
628
|
+
kind: "text";
|
|
629
|
+
text: string;
|
|
630
|
+
} | {
|
|
631
|
+
kind: "tool";
|
|
632
|
+
name: string;
|
|
633
|
+
summary: string;
|
|
634
|
+
toolUseId: string | null;
|
|
635
|
+
} | {
|
|
636
|
+
kind: "result";
|
|
637
|
+
toolUseId: string | null;
|
|
638
|
+
text: string;
|
|
639
|
+
isError: boolean;
|
|
640
|
+
}>;
|
|
641
|
+
}>;
|
|
642
|
+
before: number | null;
|
|
643
|
+
/** How many items the redactor replaced on this page. */
|
|
644
|
+
redacted: number;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
/** What GET /v1/routines returns (`routine-registry.mjs list --json`): the routines saved with /multi-agent:save. Description and source are scrubbed. */
|
|
648
|
+
export interface Routines {
|
|
649
|
+
contractVersion: string;
|
|
650
|
+
routines: Array<{
|
|
651
|
+
name: string;
|
|
652
|
+
description: string;
|
|
653
|
+
createdAt: string | null;
|
|
654
|
+
source: string | null;
|
|
655
|
+
}>;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
/** What DELETE /v1/routines/{name} returns. Without ?confirm: preview (the routine) with confirmToken and expiresAt. With it: removed, from `routine-registry.mjs remove`. A shipped command is never removed. */
|
|
659
|
+
export interface RoutineDelete {
|
|
660
|
+
contractVersion: string;
|
|
661
|
+
preview?: {
|
|
662
|
+
name: string;
|
|
663
|
+
description: string;
|
|
664
|
+
createdAt: string | null;
|
|
665
|
+
source: string | null;
|
|
666
|
+
};
|
|
667
|
+
confirmToken?: string;
|
|
668
|
+
expiresAt?: string;
|
|
669
|
+
removed?: {
|
|
670
|
+
name: string;
|
|
671
|
+
removedDir: boolean;
|
|
672
|
+
removedEntry: boolean;
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
/** What GET /v1/stack?repo= returns (`stack-toggle.mjs status --json`): the stacks a repository enables in .claude/settings.json and every marketplace plugin with its skills. manifestVerified is false when the marketplace manifest could not be read and the plugin list is the convention. */
|
|
677
|
+
export interface Stack {
|
|
678
|
+
contractVersion: string;
|
|
679
|
+
stacks: Array<string>;
|
|
680
|
+
knownStacks: Array<string>;
|
|
681
|
+
plugins: Array<{
|
|
682
|
+
name: string;
|
|
683
|
+
enabled: boolean;
|
|
684
|
+
alwaysOn: boolean;
|
|
685
|
+
stack: string | null;
|
|
686
|
+
skills: Array<string>;
|
|
687
|
+
}>;
|
|
688
|
+
manifestVerified: boolean;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
/** The body of POST /v1/stack. The first request names repo (a name from GET /v1/repos or its path) and stacks (as /multi-agent:stack takes them, aliases allowed); the second sends only confirmToken. */
|
|
692
|
+
export interface StackRequest {
|
|
693
|
+
contractVersion: string;
|
|
694
|
+
repo?: string;
|
|
695
|
+
stacks?: Array<string>;
|
|
696
|
+
confirmToken?: string;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
/** What POST /v1/stack returns (`stack-toggle.mjs set`). Step one: preview {stacks, changed, enabledPlugins, dropped} with confirmToken and expiresAt, nothing written. Step two: the written enabledPlugins, the keys that changed and written. */
|
|
700
|
+
export interface StackChange {
|
|
701
|
+
contractVersion: string;
|
|
702
|
+
preview?: {
|
|
703
|
+
stacks: Array<string>;
|
|
704
|
+
changed: Array<string>;
|
|
705
|
+
enabledPlugins: {
|
|
706
|
+
[key: string]: boolean;
|
|
707
|
+
};
|
|
708
|
+
dropped: Array<string>;
|
|
709
|
+
};
|
|
710
|
+
confirmToken?: string;
|
|
711
|
+
expiresAt?: string;
|
|
712
|
+
stacks?: Array<string>;
|
|
713
|
+
enabledPlugins?: {
|
|
714
|
+
[key: string]: boolean;
|
|
715
|
+
};
|
|
716
|
+
changed?: Array<string>;
|
|
717
|
+
dropped?: Array<string>;
|
|
718
|
+
written?: boolean;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
/** The body of POST /v1/autopilot/on. The first request names the selection (repos, by nameWithOwner, each already in the autopilot config) and gets a preview and a confirm token; the second sends only the token and turns the mode on for exactly what was previewed. An empty selection is refused: the mode is never turned on without a repository. */
|
|
722
|
+
export interface AutopilotOnRequest {
|
|
723
|
+
contractVersion: string;
|
|
724
|
+
repos?: Array<string>;
|
|
725
|
+
/** Save the selection without scheduling anything. */
|
|
726
|
+
configureOnly?: boolean;
|
|
727
|
+
confirmToken?: string;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
/** What POST /v1/autopilot/on returns (`autopilot-control.mjs on-preview`, then `on`). Step one: preview {keep, drop, probe, configureOnly} with confirmToken and expiresAt. Step two: enabled and scheduled say whether the schedule was loaded; it is not when configureOnly was asked or a credential probe failed, and probe says which. */
|
|
731
|
+
export interface AutopilotOn {
|
|
732
|
+
contractVersion: string;
|
|
733
|
+
preview?: {
|
|
734
|
+
keep: Array<string>;
|
|
735
|
+
drop: Array<string>;
|
|
736
|
+
probe: {
|
|
737
|
+
ready: boolean;
|
|
738
|
+
problems: Array<string>;
|
|
739
|
+
warnings: Array<string>;
|
|
740
|
+
};
|
|
741
|
+
configureOnly: boolean;
|
|
742
|
+
};
|
|
743
|
+
confirmToken?: string;
|
|
744
|
+
expiresAt?: string;
|
|
745
|
+
enabled?: boolean;
|
|
746
|
+
scheduled?: boolean;
|
|
747
|
+
awake?: boolean | null;
|
|
748
|
+
repos?: Array<string>;
|
|
749
|
+
dropped?: Array<string>;
|
|
750
|
+
probe?: {
|
|
751
|
+
ready: boolean;
|
|
752
|
+
problems: Array<string>;
|
|
753
|
+
warnings: Array<string>;
|
|
754
|
+
};
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
/** The body of POST /v1/runs/{id}/steer. The first request carries text (verbatim, up to 4000 characters) and gets a preview and a confirm token bound to the run and that text; the second carries only confirmToken. */
|
|
758
|
+
export interface SteerRequest {
|
|
759
|
+
contractVersion: string;
|
|
760
|
+
text?: string;
|
|
761
|
+
confirmToken?: string;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
/** What POST /v1/runs/{id}/steer returns (`steer-run.mjs`). Step one: preview {text, status, currentPhase, replaces} with confirmToken and expiresAt, nothing written. Step two: the instruction is queued as the run's pendingSteer and applied at the entry to its next phase; replaced is the unconsumed instruction it replaced, or null. */
|
|
765
|
+
export interface Steer {
|
|
766
|
+
contractVersion: string;
|
|
767
|
+
taskId: string;
|
|
768
|
+
queuedAt?: string;
|
|
769
|
+
replaced?: string | null;
|
|
770
|
+
status?: string | null;
|
|
771
|
+
currentPhase?: number | null;
|
|
772
|
+
preview?: {
|
|
773
|
+
text: string;
|
|
774
|
+
status: string | null;
|
|
775
|
+
currentPhase: number | null;
|
|
776
|
+
replaces: string | null;
|
|
777
|
+
};
|
|
778
|
+
confirmToken?: string;
|
|
779
|
+
expiresAt?: string;
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
/** What GET /v1/ledger returns and `office-ledger.mjs --json` prints: tokens and estimated USD for today, this week (from Monday) and this month, in local time, broken down by run, repository, model and phase. A run's numbers come from its tracker-state.json when the tracker carries tokens, else from the usage records of the transcripts tied to it; a run with neither is not-measured, and its usd and tokens are null, never 0. Sessions no run claims are counted apart as outside the pipeline. Prices come from cost-table.json; a cache write is priced at 1.25 times input. Every amount names its source. */
|
|
783
|
+
export interface Ledger {
|
|
784
|
+
contractVersion: string;
|
|
785
|
+
generatedAt: string;
|
|
786
|
+
prices: {
|
|
787
|
+
table: "cost-table.json";
|
|
788
|
+
verifiedAt: string | null;
|
|
789
|
+
ageDays: number | null;
|
|
790
|
+
stale: boolean;
|
|
791
|
+
warning: string | null;
|
|
792
|
+
};
|
|
793
|
+
windows: {
|
|
794
|
+
today: LedgerWindow;
|
|
795
|
+
week: LedgerWindow;
|
|
796
|
+
month: LedgerWindow;
|
|
797
|
+
};
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
/** tracker-state: the pipeline's own ledger; transcript: derived from the host's usage records; mixed: a sum of both kinds; not-measured: nothing could be read, so the numbers are null. */
|
|
801
|
+
export type LedgerSource = "tracker-state" | "transcript" | "mixed" | "not-measured";
|
|
802
|
+
|
|
803
|
+
export type LedgerTokens = {
|
|
804
|
+
in: number;
|
|
805
|
+
out: number;
|
|
806
|
+
cacheRead: number;
|
|
807
|
+
cacheWrite: number;
|
|
808
|
+
} | null;
|
|
809
|
+
|
|
810
|
+
export interface LedgerAmount {
|
|
811
|
+
tokens: LedgerTokens;
|
|
812
|
+
usd: number | null;
|
|
813
|
+
source: LedgerSource;
|
|
814
|
+
/** Usage records whose model has no price; their tokens are counted, their cost is not. */
|
|
815
|
+
unpriced: number;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
export interface LedgerRow {
|
|
819
|
+
key: string;
|
|
820
|
+
/** On byRun rows: the run repository. */
|
|
821
|
+
repo?: string | null;
|
|
822
|
+
tokens: LedgerTokens;
|
|
823
|
+
usd: number | null;
|
|
824
|
+
source: LedgerSource;
|
|
825
|
+
unpriced: number;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
export interface LedgerWindow {
|
|
829
|
+
since: string;
|
|
830
|
+
total: LedgerAmount;
|
|
831
|
+
outsidePipeline: LedgerAmount;
|
|
832
|
+
/** Task ids of runs active in the window whose cost could not be measured. */
|
|
833
|
+
notMeasured: Array<string>;
|
|
834
|
+
byRun: Array<LedgerRow>;
|
|
835
|
+
byRepo: Array<LedgerRow>;
|
|
836
|
+
byModel: Array<LedgerRow>;
|
|
837
|
+
byPhase: Array<LedgerRow>;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
/** What GET /v1/runs/{id}/results returns (`run-results.mjs <id> --json`): what a run produced, read from its own files. diff from agent-state diffRisk or .review-diff.txt; findings from triage-output.json or agent-state review; tests from the test-summary gate and uiTest; evidence the screenshot names under .pipeline/evidence; analysis the documents an analysis run wrote. A part with no source is null. Text is scrubbed and redacted; paths are reduced to file names. */
|
|
841
|
+
export interface RunResults {
|
|
842
|
+
contractVersion: string;
|
|
843
|
+
taskId: string;
|
|
844
|
+
diff: {
|
|
845
|
+
files: number;
|
|
846
|
+
added: number | null;
|
|
847
|
+
removed: number | null;
|
|
848
|
+
maxScore: number | null;
|
|
849
|
+
signals: Array<string>;
|
|
850
|
+
changed: Array<string>;
|
|
851
|
+
source: string;
|
|
852
|
+
} | null;
|
|
853
|
+
findings: {
|
|
854
|
+
approved: boolean | null;
|
|
855
|
+
items: Array<{
|
|
856
|
+
severity: string;
|
|
857
|
+
file: string | null;
|
|
858
|
+
line: number | null;
|
|
859
|
+
issue: string;
|
|
860
|
+
fix: string | null;
|
|
861
|
+
reviewer: string | null;
|
|
862
|
+
verdict: string;
|
|
863
|
+
}>;
|
|
864
|
+
total: number;
|
|
865
|
+
source: string;
|
|
866
|
+
} | null;
|
|
867
|
+
tests: {
|
|
868
|
+
status: string | null;
|
|
869
|
+
passed: number | null;
|
|
870
|
+
failed: number | null;
|
|
871
|
+
skipped: number | null;
|
|
872
|
+
uiTest: {
|
|
873
|
+
ran: boolean;
|
|
874
|
+
status: string | null;
|
|
875
|
+
notRunReason: string | null;
|
|
876
|
+
} | null;
|
|
877
|
+
source: string;
|
|
878
|
+
} | null;
|
|
879
|
+
evidence: Array<{
|
|
880
|
+
name: string;
|
|
881
|
+
phase: "before" | "after" | null;
|
|
882
|
+
}>;
|
|
883
|
+
analysis: {
|
|
884
|
+
documents: Array<{
|
|
885
|
+
name: string;
|
|
886
|
+
text: string | null;
|
|
887
|
+
}>;
|
|
888
|
+
confluencePages: number;
|
|
889
|
+
jiraIssueKey: string | null;
|
|
890
|
+
} | null;
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
/** What GET /v1/runs/{id}/evidence/{name} returns (`run-results.mjs <id> --evidence <name>`): one screenshot from the run's .pipeline/evidence directory, base64. name is a bare png or jpg file name; one that resolves outside the directory is not found. */
|
|
894
|
+
export interface RunEvidence {
|
|
895
|
+
contractVersion: string;
|
|
896
|
+
taskId: string;
|
|
897
|
+
name: string;
|
|
898
|
+
mime: "image/png" | "image/jpeg";
|
|
899
|
+
data: string;
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
/** What GET /v1/issues/{key}/maturity returns (`work-items.mjs maturity <key>`, from lib/issue-fetcher.sh): the maturity check the pipeline runs before it starts on an issue. key is a Jira key, owner/repo#N or #N. Blockers stop a run; warnings are asked about. Text is redacted. */
|
|
903
|
+
export interface IssueMaturity {
|
|
904
|
+
contractVersion: string;
|
|
905
|
+
key: string;
|
|
906
|
+
kind: "jira" | "github" | "freetext";
|
|
907
|
+
title: string;
|
|
908
|
+
type: string | null;
|
|
909
|
+
status: string | null;
|
|
910
|
+
maturity: {
|
|
911
|
+
score: number | null;
|
|
912
|
+
blockers: Array<string>;
|
|
913
|
+
warnings: Array<string>;
|
|
914
|
+
summary: string | null;
|
|
915
|
+
};
|
|
916
|
+
description: string | null;
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
/** What GET /v1/prs returns (`work-items.mjs prs`): open pull requests where you are asked to review or are the author. sources says per host whether it was read; Bitbucket listing is not implemented and says so rather than showing an empty list. url is dropped under redact. */
|
|
920
|
+
export interface Prs {
|
|
921
|
+
contractVersion: string;
|
|
922
|
+
items: Array<{
|
|
923
|
+
source: "github" | "bitbucket";
|
|
924
|
+
repo: string;
|
|
925
|
+
number: number;
|
|
926
|
+
title: string;
|
|
927
|
+
url: string | null;
|
|
928
|
+
author: string | null;
|
|
929
|
+
updatedAt: string | null;
|
|
930
|
+
role: "reviewer" | "author";
|
|
931
|
+
}>;
|
|
932
|
+
sources: Array<{
|
|
933
|
+
source: string;
|
|
934
|
+
ok: boolean;
|
|
935
|
+
count: number;
|
|
936
|
+
reason?: string;
|
|
937
|
+
}>;
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
/** The body of POST /v1/runs/{id}/review-verdict: empty for the preview, confirmToken to post. The verdict is never chosen by the request; it follows from the review's recorded findings. */
|
|
941
|
+
export interface ReviewVerdictRequest {
|
|
942
|
+
contractVersion: string;
|
|
943
|
+
confirmToken?: string;
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
/** What POST /v1/runs/{id}/review-verdict returns (`work-items.mjs verdict <id> [--post]`). Only a finished review whose every finding is triaged (accepted, rejected or deferred) is previewed (409 review-incomplete otherwise). The preview carries findingsDigest, the hash of the findings it was made from, and the decision lib/post-pr-review.sh would post (approve with no accepted blocking or important finding, else needs-work), a confirmToken bound to that decision and digest, and expiresAt; a confirmation after either changed is 409 confirm-mismatch; the confirmation runs post-pr-review.sh, which posts the comments and the verdict with the user's own credential, and says posted. */
|
|
947
|
+
export interface ReviewVerdict {
|
|
948
|
+
contractVersion: string;
|
|
949
|
+
taskId: string;
|
|
950
|
+
provider: "github" | "bitbucket-server" | null;
|
|
951
|
+
prNumber: number | null;
|
|
952
|
+
decision: "approve" | "needs-work";
|
|
953
|
+
acceptedBlocking: number;
|
|
954
|
+
acceptedImportant: number;
|
|
955
|
+
findings: number;
|
|
956
|
+
posted?: boolean;
|
|
957
|
+
confirmToken?: string;
|
|
958
|
+
expiresAt?: string;
|
|
959
|
+
findingsDigest: string;
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
/** What GET /v1/tools returns (`toolkit-tools.mjs list`): every tool the registered multi-agent-toolkit MCP server serves, with its category (the name's prefix), risk from its own annotations (readOnlyHint read, destructiveHint high, else low) and its inputSchema, from which a client builds the form. Calls are denied by default; allowed says which tools can be called and reason why the others cannot. */
|
|
963
|
+
export interface Tools {
|
|
964
|
+
contractVersion: string;
|
|
965
|
+
tools: Array<{
|
|
966
|
+
name: string;
|
|
967
|
+
title: string | null;
|
|
968
|
+
category: string;
|
|
969
|
+
description: string;
|
|
970
|
+
risk: "read" | "low" | "high";
|
|
971
|
+
inputSchema: Record<string, unknown>;
|
|
972
|
+
/** Whether POST /v1/tools/{name}/call accepts this tool: only a readOnlyHint tool whose inputSchema takes no location (path, URL, file, directory, output, project, root) and that is not in the web or context family. */
|
|
973
|
+
allowed: boolean;
|
|
974
|
+
reason: string | null;
|
|
975
|
+
}>;
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
/** The body of POST /v1/tools/{name}/call: the tool's arguments, which must satisfy its inputSchema. At most 64 KiB. */
|
|
979
|
+
export interface ToolCallRequest {
|
|
980
|
+
contractVersion: string;
|
|
981
|
+
arguments?: Record<string, unknown>;
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
/** What POST /v1/tools/{name}/call returns (`toolkit-tools.mjs call`): the tool's result as text, JSON (as text) and images (base64, image types only). Every text is redacted. */
|
|
985
|
+
export interface ToolCall {
|
|
986
|
+
contractVersion: string;
|
|
987
|
+
tool: string;
|
|
988
|
+
risk: "read" | "low" | "high";
|
|
989
|
+
isError: boolean;
|
|
990
|
+
content: Array<{
|
|
991
|
+
kind: "text" | "json" | "image";
|
|
992
|
+
text?: string;
|
|
993
|
+
mime?: string;
|
|
994
|
+
data?: string;
|
|
995
|
+
}>;
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
/** What GET /v1/services/confluence, /crashlytics and /figma return (`service-read.mjs`): one Confluence page, one Crashlytics issue or one Figma frame render, through the pipeline's own clients. Text is redacted; a frame comes back as base64 PNG. */
|
|
999
|
+
export interface ServiceRead {
|
|
1000
|
+
contractVersion: string;
|
|
1001
|
+
service: "confluence" | "crashlytics" | "figma";
|
|
1002
|
+
pageId?: string | null;
|
|
1003
|
+
title?: string;
|
|
1004
|
+
body?: string;
|
|
1005
|
+
apiContracts?: number;
|
|
1006
|
+
type?: string | null;
|
|
1007
|
+
occurrences?: number | null;
|
|
1008
|
+
impactedUsers?: number | null;
|
|
1009
|
+
stackTrace?: Array<string>;
|
|
1010
|
+
fileKey?: string;
|
|
1011
|
+
nodeId?: string;
|
|
1012
|
+
mime?: "image/png";
|
|
1013
|
+
data?: string;
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
/** What GET /v1/permissions returns: the host permission prompts waiting on the user. available is false while the host records none where another process can read them; requests is then empty and reason says so. When available, each request names its session, the tool and a redacted summary. */
|
|
1017
|
+
export interface Permissions {
|
|
1018
|
+
contractVersion: string;
|
|
1019
|
+
available: boolean;
|
|
1020
|
+
reason: string | null;
|
|
1021
|
+
requests: Array<{
|
|
1022
|
+
id: string;
|
|
1023
|
+
sessionId: string;
|
|
1024
|
+
tool: string;
|
|
1025
|
+
summary: string;
|
|
1026
|
+
at: string;
|
|
1027
|
+
}>;
|
|
1028
|
+
}
|
|
1029
|
+
|
|
503
1030
|
/** Every non-2xx body contract-server.mjs sends, on the desktop and the phone routes alike. `error` is a fixed code a client switches on; `message` is for a person and names no path, host or token. `errors` lists schema or rule violations for invalid-body and invalid-request; `supported` lists the majors ?v= accepts for unsupported-version. run-active and not-resumable answer POST /v1/runs/{id}/resume; confirm-expired and confirm-mismatch answer the confirming request of a kill or gc. */
|
|
504
1031
|
export interface ContractError {
|
|
505
1032
|
contractVersion: string;
|
|
506
|
-
error: "unauthorized" | "forbidden-host" | "forbidden-origin" | "not-found" | "method-not-allowed" | "invalid-query" | "unsupported-version" | "unsupported-media-type" | "invalid-body" | "invalid-request" | "no-launch-shape" | "not-waiting" | "wrong-question" | "wrong-arity" | "not-an-option" | "state-moved" | "unsigned" | "unknown-device" | "revoked-device" | "bad-signature" | "stale-request" | "replayed" | "replay-store-full" | "unknown-verb" | "forbidden-scope" | "launch-disabled" | "repo-not-allowed" | "run-active" | "not-resumable" | "confirm-expired" | "confirm-mismatch" | "unattended-profile-missing" | "workspace-not-trusted" | "internal";
|
|
1033
|
+
error: "unauthorized" | "forbidden-host" | "forbidden-origin" | "not-found" | "method-not-allowed" | "invalid-query" | "unsupported-version" | "unsupported-media-type" | "invalid-body" | "invalid-request" | "no-launch-shape" | "not-waiting" | "wrong-question" | "wrong-arity" | "not-an-option" | "state-moved" | "unsigned" | "unknown-device" | "revoked-device" | "bad-signature" | "stale-request" | "replayed" | "replay-store-full" | "unknown-verb" | "forbidden-scope" | "launch-disabled" | "repo-not-allowed" | "run-active" | "not-resumable" | "confirm-expired" | "confirm-mismatch" | "unattended-profile-missing" | "workspace-not-trusted" | "no-selection" | "repo-not-configured" | "invalid-config" | "not-installed" | "repo-ambiguous" | "unreadable-settings" | "not-removable" | "not-steerable" | "too-many-streams" | "no-review" | "upstream-failed" | "tool-not-allowed" | "busy" | "review-incomplete" | "host-not-allowed" | "internal";
|
|
507
1034
|
message: string;
|
|
508
1035
|
errors?: Array<string>;
|
|
509
1036
|
supported?: Array<number>;
|