@danypops/papyrus 0.44.8 → 0.44.10
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/package.json +3 -2
- package/src/{ports → artifact}/artifact-event-reader.ts +1 -1
- package/src/{artifact-relationship-view.ts → artifact/artifact-relationship-view.ts} +3 -3
- package/src/{ports → artifact}/artifact-store.ts +2 -2
- package/src/{artifact-subtree.ts → artifact/artifact-subtree.ts} +4 -4
- package/src/{ports → artifact}/artifact-trash-store.ts +2 -2
- package/src/{adapters → artifact}/sqlite-artifact-scope-store.ts +1 -1
- package/src/{adapters → artifact}/sqlite-artifact-store.ts +15 -15
- package/src/authority-registry.ts +3 -3
- package/src/cli/artifact-command.ts +210 -0
- package/src/cli/discuss-command.ts +256 -0
- package/src/cli/docs-command.ts +192 -0
- package/src/cli/gates-command.ts +46 -0
- package/src/cli/graph-command.ts +171 -0
- package/src/cli/graph-projection-command.ts +79 -0
- package/src/cli/log-command.ts +101 -0
- package/src/cli/migration-command.ts +40 -0
- package/src/cli/note-command.ts +186 -0
- package/src/cli/playbooks-command.ts +313 -0
- package/src/cli/rules-command.ts +220 -0
- package/src/cli/session-identity-command.ts +58 -0
- package/src/cli/shared.ts +5 -0
- package/src/cli/stricli-run.ts +30 -0
- package/src/cli/task-command.ts +892 -0
- package/src/cli.ts +32 -1914
- package/src/client.ts +2 -2
- package/src/{daemon-state.ts → daemon/daemon-state.ts} +1 -1
- package/src/{daemon.ts → daemon/daemon.ts} +3 -3
- package/src/db.ts +1 -1
- package/src/{discussion-service.ts → discussion/discussion-service.ts} +7 -6
- package/src/domain-services.ts +5 -5
- package/src/{graph-projection-service.ts → graph-projection/graph-projection-service.ts} +6 -6
- package/src/{vehicle/artifact-trash-vehicle.ts → handlers/artifact-trash.ts} +4 -4
- package/src/{vehicle/discuss-vehicle.ts → handlers/discuss.ts} +20 -25
- package/src/{vehicle/docs-vehicle.ts → handlers/docs.ts} +4 -37
- package/src/{vehicle/notes-vehicle.ts → handlers/notes.ts} +4 -38
- package/src/{vehicle/playbooks-vehicle.ts → handlers/playbooks.ts} +34 -100
- package/src/{vehicle/papyrus-vehicle.ts → handlers/registry.ts} +16 -16
- package/src/{vehicle/rules-vehicle.ts → handlers/rules.ts} +4 -37
- package/src/{vehicle/artifact-vehicle-shared.ts → handlers/shared.ts} +96 -6
- package/src/{vehicle/tasks-vehicle.ts → handlers/tasks.ts} +37 -124
- package/src/index.ts +13 -13
- package/src/{log-service.ts → log/log-service.ts} +2 -2
- package/src/modules/discuss.ts +7 -28
- package/src/modules/docs.ts +4 -24
- package/src/modules/graph-projection.ts +5 -11
- package/src/modules/logs.ts +2 -23
- package/src/modules/notes.ts +2 -23
- package/src/modules/operation-input.ts +35 -0
- package/src/modules/playbooks.ts +13 -33
- package/src/modules/rules.ts +4 -24
- package/src/modules/session-identity.ts +2 -16
- package/src/modules/tasks.ts +11 -38
- package/src/{note-service.ts → note/note-service.ts} +6 -6
- package/src/ops.ts +6 -6
- package/src/{playbook-definition.ts → playbook/playbook-definition.ts} +7 -6
- package/src/{playbook-execution.ts → playbook/playbook-execution.ts} +5 -4
- package/src/{workflow-execution.ts → playbook/workflow-execution.ts} +12 -12
- package/src/service.ts +30 -57
- package/src/{session-identity-service.ts → session-identity/session-identity-service.ts} +2 -2
- package/src/{ports → stores}/session-identity-store.ts +1 -1
- package/src/{adapters → stores}/sqlite-discussion-round-store.ts +1 -1
- package/src/{adapters → stores}/sqlite-gate-runner.ts +1 -1
- package/src/{adapters → stores}/sqlite-graph-projection-store.ts +1 -1
- package/src/{adapters → stores}/sqlite-log-store.ts +1 -1
- package/src/{adapters → stores}/sqlite-note-event-store.ts +1 -1
- package/src/{adapters → stores}/sqlite-session-identity-store.ts +1 -1
- package/src/{adapters → stores}/sqlite-task-event-store.ts +1 -1
- package/src/{adapters → stores}/sqlite-task-focus-store.ts +1 -1
- package/src/{adapters → stores}/sqlite-task-lease-store.ts +1 -1
- package/src/{adapters → stores}/sqlite-task-scope-store.ts +1 -1
- package/src/{task-context.ts → task/task-context.ts} +4 -4
- package/src/{task-execution.ts → task/task-execution.ts} +1 -1
- package/src/{task-graph-view.ts → task/task-graph-view.ts} +1 -1
- package/src/{task-relationship-view.ts → task/task-relationship-view.ts} +3 -3
- package/src/{task-service.ts → task/task-service.ts} +14 -14
- /package/src/{domain → artifact}/artifact-alias.ts +0 -0
- /package/src/{domain → artifact}/artifact-event.ts +0 -0
- /package/src/{ports → artifact}/artifact-scope-store.ts +0 -0
- /package/src/{domain → artifact}/artifact-trash.ts +0 -0
- /package/src/{domain → artifact}/artifact.ts +0 -0
- /package/src/{ports → artifact}/atomic-artifact-store.ts +0 -0
- /package/src/{log.ts → log/log.ts} +0 -0
- /package/src/{ports → stores}/discussion-round-store.ts +0 -0
- /package/src/{ports → stores}/gate-runner.ts +0 -0
- /package/src/{ports → stores}/graph-projection-store.ts +0 -0
- /package/src/{ports → stores}/graph-renderer.ts +0 -0
- /package/src/{ports → stores}/log-store.ts +0 -0
- /package/src/{ports → stores}/note-event-store.ts +0 -0
- /package/src/{ports → stores}/task-event-store.ts +0 -0
- /package/src/{ports → stores}/task-focus-store.ts +0 -0
- /package/src/{ports → stores}/task-lease-store.ts +0 -0
- /package/src/{ports → stores}/task-scope-store.ts +0 -0
package/src/client.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { fileURLToPath } from "node:url";
|
|
|
3
3
|
import { connectWithVersionCheck, type ExpectedVersion, spawnDetachedDaemon } from "@danypops/vehicle-client/daemon-client";
|
|
4
4
|
import { createLiveVersionExpectation } from "@danypops/vehicle-client/version";
|
|
5
5
|
import { DAEMON_CLIENT_TIMEOUT_MS, DAEMON_DIR_ENV, DAEMON_PROBE_TIMEOUT_MS } from "./constants.ts";
|
|
6
|
-
import { type DaemonHandle, daemonStateDir, readDaemonHandle } from "./daemon-state.ts";
|
|
6
|
+
import { type DaemonHandle, daemonStateDir, readDaemonHandle } from "./daemon/daemon-state.ts";
|
|
7
7
|
import type { OperationName, SchemaState } from "./service.ts";
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -161,7 +161,7 @@ export function resolvePushChannelTarget(dir: string = daemonStateDir()): PushCh
|
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
export interface VehicleClientTarget {
|
|
164
|
-
/** Base URL for a domain migrated onto VehicleRegistry (see src/
|
|
164
|
+
/** Base URL for a domain migrated onto VehicleRegistry (see src/handlers/*.ts) -- @danypops/vehicle-client's RemoteVehicleClient mounts its own /vehicle/manifest, /vehicle/invoke, /vehicle/cancel routes under this. */
|
|
165
165
|
baseUrl: string;
|
|
166
166
|
token: string;
|
|
167
167
|
}
|
|
@@ -3,7 +3,7 @@ import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { LOOPBACK_HOST, removeDaemonHandle, writeDaemonHandle } from "@danypops/vehicle-server/paths";
|
|
6
|
-
import { DAEMON_DIR_ENV, DAEMON_HANDLE_FILE, DAEMON_HOST, DAEMON_PORT_FILE, DAEMON_TOKEN_FILE } from "
|
|
6
|
+
import { DAEMON_DIR_ENV, DAEMON_HANDLE_FILE, DAEMON_HOST, DAEMON_PORT_FILE, DAEMON_TOKEN_FILE } from "../constants.ts";
|
|
7
7
|
|
|
8
8
|
export interface DaemonHandle {
|
|
9
9
|
baseUrl: string;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
2
|
import { acquireDaemonLock, releaseDaemonLock } from "@danypops/vehicle-server/paths";
|
|
3
3
|
import { PushChannel } from "@danypops/vehicle-server/push-channel";
|
|
4
|
-
import { DAEMON_HOST, DB_OPTIMIZE_INTERVAL_MS, dbPath, WAL_CHECKPOINT_INTERVAL_MS } from "
|
|
4
|
+
import { DAEMON_HOST, DB_OPTIMIZE_INTERVAL_MS, dbPath, WAL_CHECKPOINT_INTERVAL_MS } from "../constants.ts";
|
|
5
|
+
import { logEvent, vehicleLogger } from "../log/log.ts";
|
|
6
|
+
import { createApp, createPapyrusService } from "../service.ts";
|
|
5
7
|
import {
|
|
6
8
|
clearDaemonPort,
|
|
7
9
|
clearVehicleHandle,
|
|
@@ -10,8 +12,6 @@ import {
|
|
|
10
12
|
writeDaemonPort,
|
|
11
13
|
writeVehicleHandle,
|
|
12
14
|
} from "./daemon-state.ts";
|
|
13
|
-
import { logEvent, vehicleLogger } from "./log.ts";
|
|
14
|
-
import { createApp, createPapyrusService } from "./service.ts";
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Operations that never change what a Task-graph reader (the pi-papyrus widget's
|
package/src/db.ts
CHANGED
|
@@ -2,8 +2,8 @@ import { mkdirSync } from "node:fs";
|
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { dirname } from "node:path";
|
|
4
4
|
import { runMigrations, type SqliteMigrationRunner } from "@danypops/vehicle-server/storage";
|
|
5
|
+
import { generateUniqueAlias, slugify } from "./artifact/artifact-alias.ts";
|
|
5
6
|
import { SQLITE_BUSY_TIMEOUT_MS, SQLITE_SCHEMA_VERSION } from "./constants.ts";
|
|
6
|
-
import { generateUniqueAlias, slugify } from "./domain/artifact-alias.ts";
|
|
7
7
|
|
|
8
8
|
const require_ = createRequire(import.meta.url);
|
|
9
9
|
const IS_BUN = typeof (globalThis as { Bun?: unknown }).Bun !== "undefined";
|
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
* append-only rounds (via DiscussionRoundStore). See domain/discussion.ts for the full
|
|
4
4
|
* design rationale.
|
|
5
5
|
*/
|
|
6
|
-
|
|
7
|
-
import type { Artifact } from "
|
|
8
|
-
import type { ArtifactEventContext } from "
|
|
6
|
+
|
|
7
|
+
import type { Artifact } from "../artifact/artifact.ts";
|
|
8
|
+
import type { ArtifactEventContext } from "../artifact/artifact-event.ts";
|
|
9
|
+
import type { AtomicArtifactStore } from "../artifact/atomic-artifact-store.ts";
|
|
10
|
+
import { DISCUSSION_LIST_DEFAULT_LIMIT, DISCUSSION_LIST_MAX_LIMIT, DISCUSSION_MAX_ROUNDS } from "../constants.ts";
|
|
9
11
|
import {
|
|
10
12
|
DISCUSSION_SUBTYPE,
|
|
11
13
|
type DiscussionExtra,
|
|
@@ -19,9 +21,8 @@ import {
|
|
|
19
21
|
validateDiscussionOptions,
|
|
20
22
|
validateSelectedOptions,
|
|
21
23
|
validateSettlement,
|
|
22
|
-
} from "
|
|
23
|
-
import type {
|
|
24
|
-
import type { DiscussionRoundStore } from "./ports/discussion-round-store.ts";
|
|
24
|
+
} from "../domain/discussion.ts";
|
|
25
|
+
import type { DiscussionRoundStore } from "../stores/discussion-round-store.ts";
|
|
25
26
|
|
|
26
27
|
export class DiscussionError extends Error {}
|
|
27
28
|
|
package/src/domain-services.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { type Artifact, requireLocallyOwnedContent } from "./artifact/artifact.ts";
|
|
2
|
+
import type { ArtifactEventContext } from "./artifact/artifact-event.ts";
|
|
3
|
+
import type { ArtifactScopeStore } from "./artifact/artifact-scope-store.ts";
|
|
4
|
+
import type { ArtifactStore } from "./artifact/artifact-store.ts";
|
|
1
5
|
import type { ArtifactAction, AuthorityRegistry } from "./authority-registry.ts";
|
|
2
6
|
import {
|
|
3
7
|
ARTIFACT_BODY_MAX_LENGTH,
|
|
@@ -14,8 +18,6 @@ import {
|
|
|
14
18
|
RULE_TEXT_HARD_LIMIT_CHARACTERS,
|
|
15
19
|
SKILL_MAX_ENUM_VALUES,
|
|
16
20
|
} from "./constants.ts";
|
|
17
|
-
import { type Artifact, requireLocallyOwnedContent } from "./domain/artifact.ts";
|
|
18
|
-
import type { ArtifactEventContext } from "./domain/artifact-event.ts";
|
|
19
21
|
import {
|
|
20
22
|
BLUEPRINT_INPUT_TYPES,
|
|
21
23
|
type BlueprintArgumentValue,
|
|
@@ -23,9 +25,7 @@ import {
|
|
|
23
25
|
validateArgumentValue,
|
|
24
26
|
} from "./domain/blueprint-definition.ts";
|
|
25
27
|
import { normalizeProjectRoot } from "./domain/task-scope.ts";
|
|
26
|
-
import { NOTE_SUBTYPE } from "./note-service.ts";
|
|
27
|
-
import type { ArtifactScopeStore } from "./ports/artifact-scope-store.ts";
|
|
28
|
-
import type { ArtifactStore } from "./ports/artifact-store.ts";
|
|
28
|
+
import { NOTE_SUBTYPE } from "./note/note-service.ts";
|
|
29
29
|
|
|
30
30
|
export interface UpdateContentInput {
|
|
31
31
|
title?: string;
|
|
@@ -4,16 +4,16 @@
|
|
|
4
4
|
* documented, deliberate scope limits of this first walking-skeleton slice.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import type {
|
|
7
|
+
import type { ArtifactStore } from "../artifact/artifact-store.ts";
|
|
8
|
+
import { requireAtomicArtifactStore } from "../artifact/atomic-artifact-store.ts";
|
|
9
|
+
import type { AuthorityRegistry } from "../authority-registry.ts";
|
|
8
10
|
import {
|
|
9
11
|
GRAPH_PROJECTION_ID_MAX_LENGTH,
|
|
10
12
|
GRAPH_PROJECTION_MAX_ARTIFACTS_PER_BATCH,
|
|
11
13
|
GRAPH_PROJECTION_MAX_EDGES_PER_BATCH,
|
|
12
|
-
} from "
|
|
13
|
-
import { GRAPH_PROJECTION_SCHEMA_VERSION, type GraphProjectionBatch, type GraphProjectionResult } from "
|
|
14
|
-
import type {
|
|
15
|
-
import { requireAtomicArtifactStore } from "./ports/atomic-artifact-store.ts";
|
|
16
|
-
import type { GraphProjectionStore } from "./ports/graph-projection-store.ts";
|
|
14
|
+
} from "../constants.ts";
|
|
15
|
+
import { GRAPH_PROJECTION_SCHEMA_VERSION, type GraphProjectionBatch, type GraphProjectionResult } from "../domain/graph-projection.ts";
|
|
16
|
+
import type { GraphProjectionStore } from "../stores/graph-projection-store.ts";
|
|
17
17
|
|
|
18
18
|
function boundedId(value: string, label: string): string {
|
|
19
19
|
if (!value || value.length === 0) throw new Error(`${label} is required`);
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { bindVehicleOperation, defineVehicleOperation } from "@danypops/vehicle-core";
|
|
7
7
|
import type { VehicleRegistry } from "@danypops/vehicle-server";
|
|
8
|
-
import {
|
|
9
|
-
import
|
|
10
|
-
import type { ArtifactTrashStore } from "../
|
|
11
|
-
import { looseObjectSchema, numberProp, passthroughOutput, stringProp, validationError } from "./
|
|
8
|
+
import type { ArtifactStore } from "../artifact/artifact-store.ts";
|
|
9
|
+
import { removeArtifactSubtree } from "../artifact/artifact-subtree.ts";
|
|
10
|
+
import type { ArtifactTrashStore } from "../artifact/artifact-trash-store.ts";
|
|
11
|
+
import { looseObjectSchema, numberProp, passthroughOutput, stringProp, validationError } from "./shared.ts";
|
|
12
12
|
|
|
13
13
|
const OWNER = "artifact";
|
|
14
14
|
const LIMITS = { defaultTimeoutMs: 5_000, maxTimeoutMs: 30_000, maxRequestBytes: 65_536, maxResponseBytes: 262_144 };
|
|
@@ -13,24 +13,23 @@
|
|
|
13
13
|
* (service.ts's moduleRegistry) stays registered unchanged for pi-papyrus's
|
|
14
14
|
* own /discuss TUI, which never went through the retired mega-tool.
|
|
15
15
|
*/
|
|
16
|
-
import {
|
|
16
|
+
import type { VehicleContentBlock } from "@danypops/vehicle-core";
|
|
17
17
|
import type { VehicleRegistry } from "@danypops/vehicle-server";
|
|
18
|
-
import type {
|
|
19
|
-
import type {
|
|
18
|
+
import type { Artifact } from "../artifact/artifact.ts";
|
|
19
|
+
import type { ArtifactStore } from "../artifact/artifact-store.ts";
|
|
20
|
+
import type { DiscussionAndRounds, Discussions } from "../discussion/discussion-service.ts";
|
|
20
21
|
import { DISCUSSION_SUBTYPE, type DiscussionRound } from "../domain/discussion.ts";
|
|
21
22
|
import { discussOperations } from "../modules/discuss.ts";
|
|
22
|
-
import type { ArtifactStore } from "../ports/artifact-store.ts";
|
|
23
23
|
import {
|
|
24
|
-
|
|
24
|
+
createOperationDefiner,
|
|
25
25
|
numberProp,
|
|
26
|
-
|
|
26
|
+
type OperationSchemaProperties,
|
|
27
27
|
resolveArtifactIdWidened,
|
|
28
28
|
stringProp,
|
|
29
29
|
validationError,
|
|
30
|
-
} from "./
|
|
30
|
+
} from "./shared.ts";
|
|
31
31
|
|
|
32
32
|
const OWNER = "discuss";
|
|
33
|
-
const LIMITS = { defaultTimeoutMs: 5_000, maxTimeoutMs: 30_000, maxRequestBytes: 65_536, maxResponseBytes: 262_144 };
|
|
34
33
|
const arrayProp = { type: "array" } as const;
|
|
35
34
|
/** Purely a client-side hint (see vehicle-client-pi's interactiveFollowUps) -- never read server-side, but must still be declared or the schema's additionalProperties:false rejects it outright. */
|
|
36
35
|
const boolProp = { type: "boolean" } as const;
|
|
@@ -122,34 +121,30 @@ const optionsUnionSchema = { type: "array" } as const;
|
|
|
122
121
|
export function registerDiscussVehicleOperations(registry: VehicleRegistry, discussions: Discussions, artifacts: ArtifactStore): void {
|
|
123
122
|
const moduleOperations = new Map(discussOperations(discussions).map((op) => [op.name, op]));
|
|
124
123
|
const call = <Output>(name: string, input: Record<string, unknown>): Output => moduleOperations.get(name)!.execute(input) as Output;
|
|
124
|
+
const baseDefine = createOperationDefiner(registry, OWNER, "discuss", ["discuss:read", "discuss:write"], call);
|
|
125
125
|
|
|
126
|
+
/**
|
|
127
|
+
* Defensively shallow-copies context.input before handing it to resolve() -- unlike every
|
|
128
|
+
* other domain's resolve, discuss's own (normalizeOptions, defaultActorToAgent) mutate their
|
|
129
|
+
* argument in place, and context.input must never be the object that mutation lands on.
|
|
130
|
+
*/
|
|
126
131
|
const define = (
|
|
127
132
|
action: string,
|
|
128
133
|
description: string,
|
|
129
134
|
effect: "read" | "local-write",
|
|
130
|
-
properties:
|
|
135
|
+
properties: OperationSchemaProperties,
|
|
131
136
|
required: readonly string[],
|
|
132
137
|
resolve: (input: Record<string, unknown>) => Record<string, unknown>,
|
|
133
138
|
wrap: (raw: unknown, resolvedInput: Record<string, unknown>) => unknown = (raw) => raw,
|
|
134
139
|
): void => {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
version: 1,
|
|
140
|
+
baseDefine(
|
|
141
|
+
action,
|
|
138
142
|
description,
|
|
139
|
-
input: looseObjectSchema(properties, required),
|
|
140
|
-
output: passthroughOutput,
|
|
141
|
-
permissions: ["discuss:read", "discuss:write"],
|
|
142
143
|
effect,
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
OWNER,
|
|
148
|
-
bindVehicleOperation(operation, () => async (context) => {
|
|
149
|
-
const resolvedInput = resolve({ ...(context.input as Record<string, unknown>) });
|
|
150
|
-
const raw = call(`discuss.${action}`, resolvedInput);
|
|
151
|
-
return wrap(raw, resolvedInput);
|
|
152
|
-
}),
|
|
144
|
+
properties,
|
|
145
|
+
required,
|
|
146
|
+
(input) => resolve({ ...input }),
|
|
147
|
+
(resolvedInput) => wrap(call(`discuss.${action}`, resolvedInput), resolvedInput),
|
|
153
148
|
);
|
|
154
149
|
};
|
|
155
150
|
|
|
@@ -3,24 +3,15 @@
|
|
|
3
3
|
* Wraps modules/docs.ts's operation definitions. remove/restore/remove_subtree
|
|
4
4
|
* are not duplicated here -- see ./artifact-trash-vehicle.ts.
|
|
5
5
|
*/
|
|
6
|
-
import { bindVehicleOperation, defineVehicleOperation } from "@danypops/vehicle-core";
|
|
7
6
|
import type { VehicleRegistry } from "@danypops/vehicle-server";
|
|
7
|
+
import type { ArtifactScopeStore } from "../artifact/artifact-scope-store.ts";
|
|
8
|
+
import type { ArtifactStore } from "../artifact/artifact-store.ts";
|
|
8
9
|
import type { AuthorityRegistry } from "../authority-registry.ts";
|
|
9
10
|
import { listDocuments } from "../domain-services.ts";
|
|
10
11
|
import { docsOperations } from "../modules/docs.ts";
|
|
11
|
-
import
|
|
12
|
-
import type { ArtifactStore } from "../ports/artifact-store.ts";
|
|
13
|
-
import {
|
|
14
|
-
looseObjectSchema,
|
|
15
|
-
numberProp,
|
|
16
|
-
passthroughOutput,
|
|
17
|
-
resolveArtifactIdWidened,
|
|
18
|
-
stringProp,
|
|
19
|
-
validationError,
|
|
20
|
-
} from "./artifact-vehicle-shared.ts";
|
|
12
|
+
import { createOperationDefiner, numberProp, resolveArtifactIdWidened, stringProp, validationError } from "./shared.ts";
|
|
21
13
|
|
|
22
14
|
const OWNER = "docs";
|
|
23
|
-
const LIMITS = { defaultTimeoutMs: 5_000, maxTimeoutMs: 30_000, maxRequestBytes: 65_536, maxResponseBytes: 262_144 };
|
|
24
15
|
|
|
25
16
|
function resolveDocId(
|
|
26
17
|
artifacts: ArtifactStore,
|
|
@@ -54,31 +45,7 @@ export function registerDocsVehicleOperations(
|
|
|
54
45
|
): void {
|
|
55
46
|
const moduleOperations = new Map(docsOperations(artifacts, scopes, authority).map((op) => [op.name, op]));
|
|
56
47
|
const call = (name: string, input: Record<string, unknown>): unknown => moduleOperations.get(name)!.execute(input);
|
|
57
|
-
|
|
58
|
-
const define = (
|
|
59
|
-
action: string,
|
|
60
|
-
description: string,
|
|
61
|
-
effect: "read" | "local-write",
|
|
62
|
-
properties: Record<string, { type: string; enum?: readonly string[] }>,
|
|
63
|
-
required: readonly string[],
|
|
64
|
-
resolve: (input: Record<string, unknown>) => Record<string, unknown>,
|
|
65
|
-
): void => {
|
|
66
|
-
const operation = defineVehicleOperation({
|
|
67
|
-
name: `docs.${action}`,
|
|
68
|
-
version: 1,
|
|
69
|
-
description,
|
|
70
|
-
input: looseObjectSchema(properties, required),
|
|
71
|
-
output: passthroughOutput,
|
|
72
|
-
permissions: ["docs:read", "docs:write"],
|
|
73
|
-
effect,
|
|
74
|
-
idempotency: { mode: effect === "read" ? "safe" : "unsafe" },
|
|
75
|
-
limits: LIMITS,
|
|
76
|
-
});
|
|
77
|
-
registry.register(
|
|
78
|
-
OWNER,
|
|
79
|
-
bindVehicleOperation(operation, () => async (context) => call(`docs.${action}`, resolve(context.input))),
|
|
80
|
-
);
|
|
81
|
-
};
|
|
48
|
+
const define = createOperationDefiner(registry, OWNER, "docs", ["docs:read", "docs:write"], call);
|
|
82
49
|
|
|
83
50
|
define(
|
|
84
51
|
"create",
|
|
@@ -7,24 +7,14 @@
|
|
|
7
7
|
* input parsing. Resolves `name`/`target_name` to `id`/`target_id` server-side, in
|
|
8
8
|
* the same call -- avoids a separate round trip per name before the real call.
|
|
9
9
|
*/
|
|
10
|
-
import { bindVehicleOperation, defineVehicleOperation } from "@danypops/vehicle-core";
|
|
11
10
|
import type { VehicleRegistry } from "@danypops/vehicle-server";
|
|
11
|
+
import type { ArtifactStore } from "../artifact/artifact-store.ts";
|
|
12
12
|
import { notesOperations } from "../modules/notes.ts";
|
|
13
|
-
import { NOTE_DISPOSITIONS, type Notes } from "../note-service.ts";
|
|
14
|
-
import
|
|
15
|
-
import {
|
|
16
|
-
looseObjectSchema,
|
|
17
|
-
numberProp,
|
|
18
|
-
passthroughOutput,
|
|
19
|
-
resolveArtifactIdWidened,
|
|
20
|
-
stringProp,
|
|
21
|
-
validationError,
|
|
22
|
-
} from "./artifact-vehicle-shared.ts";
|
|
13
|
+
import { NOTE_DISPOSITIONS, type Notes } from "../note/note-service.ts";
|
|
14
|
+
import { createOperationDefiner, numberProp, resolveArtifactIdWidened, stringProp, validationError } from "./shared.ts";
|
|
23
15
|
|
|
24
16
|
const OWNER = "notes";
|
|
25
17
|
|
|
26
|
-
const LIMITS = { defaultTimeoutMs: 5_000, maxTimeoutMs: 30_000, maxRequestBytes: 65_536, maxResponseBytes: 262_144 };
|
|
27
|
-
|
|
28
18
|
/** Resolves a note's id from either an explicit id or its title within projectRoot. */
|
|
29
19
|
function resolveNoteId(artifacts: ArtifactStore, notes: Notes, projectRoot: string, id: unknown, name: unknown): string {
|
|
30
20
|
if (typeof id === "string" && id.length > 0) return id;
|
|
@@ -50,31 +40,7 @@ function resolveArtifactId(artifacts: ArtifactStore, id: unknown, name: unknown)
|
|
|
50
40
|
export function registerNotesVehicleOperations(registry: VehicleRegistry, notes: Notes, artifacts: ArtifactStore): void {
|
|
51
41
|
const moduleOperations = new Map(notesOperations(notes).map((op) => [op.name, op]));
|
|
52
42
|
const call = (name: string, input: Record<string, unknown>): unknown => moduleOperations.get(name)!.execute(input);
|
|
53
|
-
|
|
54
|
-
const define = (
|
|
55
|
-
action: string,
|
|
56
|
-
description: string,
|
|
57
|
-
effect: "read" | "local-write",
|
|
58
|
-
properties: Record<string, { type: string; enum?: readonly string[] }>,
|
|
59
|
-
required: readonly string[],
|
|
60
|
-
resolve: (input: Record<string, unknown>) => Record<string, unknown>,
|
|
61
|
-
): void => {
|
|
62
|
-
const operation = defineVehicleOperation({
|
|
63
|
-
name: `notes.${action}`,
|
|
64
|
-
version: 1,
|
|
65
|
-
description,
|
|
66
|
-
input: looseObjectSchema(properties, required),
|
|
67
|
-
output: passthroughOutput,
|
|
68
|
-
permissions: ["notes:read", "notes:write"],
|
|
69
|
-
effect,
|
|
70
|
-
idempotency: { mode: effect === "read" ? "safe" : "unsafe" },
|
|
71
|
-
limits: LIMITS,
|
|
72
|
-
});
|
|
73
|
-
registry.register(
|
|
74
|
-
OWNER,
|
|
75
|
-
bindVehicleOperation(operation, () => async (context) => call(`notes.${action}`, resolve(context.input))),
|
|
76
|
-
);
|
|
77
|
-
};
|
|
43
|
+
const define = createOperationDefiner(registry, OWNER, "notes", ["notes:read", "notes:write"], call);
|
|
78
44
|
|
|
79
45
|
define(
|
|
80
46
|
"capture",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* Those two fields never belong in this operation's model-visible inputSchema -- a model
|
|
10
10
|
* has no business knowing or supplying a session secret. Instead they travel through
|
|
11
11
|
* VehicleInvocationOptions.principal.claims, populated by pi-papyrus's own
|
|
12
|
-
* resolveInvocation hook (see vehicle-notes-client.ts) from its own already-cached
|
|
12
|
+
* resolveInvocation hook (see pi-papyrus's tools/vehicle-notes-client.ts) from its own already-cached
|
|
13
13
|
* session_secret, the same value the hand-rolled tool used to thread through as a raw
|
|
14
14
|
* input field. A caller with no cached secret for this session (unregistered, or a non-Pi
|
|
15
15
|
* Vehicle client) simply gets the guard's own no-op-when-unset default, unchanged.
|
|
@@ -18,33 +18,31 @@
|
|
|
18
18
|
* WithVehicleContent) built from the same execution-DAG summary pi-papyrus's hand-rolled
|
|
19
19
|
* tool used to build client-side.
|
|
20
20
|
*/
|
|
21
|
-
import { bindVehicleOperation, defineVehicleOperation, type VehicleOperationContext } from "@danypops/vehicle-core";
|
|
22
21
|
import type { VehicleRegistry } from "@danypops/vehicle-server";
|
|
22
|
+
import type { ArtifactScopeStore } from "../artifact/artifact-scope-store.ts";
|
|
23
|
+
import type { ArtifactStore } from "../artifact/artifact-store.ts";
|
|
23
24
|
import { listPlaybooks } from "../domain-services.ts";
|
|
24
25
|
import { playbooksOperations } from "../modules/playbooks.ts";
|
|
25
|
-
import type { PlaybookInvocationResult, PlaybookMissingArguments } from "../playbook-execution.ts";
|
|
26
|
-
import type {
|
|
27
|
-
import type {
|
|
28
|
-
import type {
|
|
29
|
-
import type {
|
|
30
|
-
import type { SessionIdentity } from "../session-identity-service.ts";
|
|
31
|
-
import type { Tasks } from "../task-service.ts";
|
|
26
|
+
import type { PlaybookInvocationResult, PlaybookMissingArguments } from "../playbook/playbook-execution.ts";
|
|
27
|
+
import type { SessionIdentity } from "../session-identity/session-identity-service.ts";
|
|
28
|
+
import type { TaskEventStore } from "../stores/task-event-store.ts";
|
|
29
|
+
import type { TaskScopeStore } from "../stores/task-scope-store.ts";
|
|
30
|
+
import type { Tasks } from "../task/task-service.ts";
|
|
32
31
|
import {
|
|
33
32
|
buildWorkflowRunContent,
|
|
34
33
|
classifyPlaybookComposition,
|
|
35
34
|
classifySessionAuthorization,
|
|
36
35
|
classifyTaskExecutionBounds,
|
|
37
|
-
|
|
36
|
+
createOperationDefiner,
|
|
37
|
+
definePairedMutation,
|
|
38
38
|
normalizeJsonEncodedField,
|
|
39
39
|
numberProp,
|
|
40
|
-
passthroughOutput,
|
|
41
40
|
resolveArtifactIdWidened,
|
|
42
41
|
stringProp,
|
|
43
42
|
validationError,
|
|
44
|
-
} from "./
|
|
43
|
+
} from "./shared.ts";
|
|
45
44
|
|
|
46
45
|
const OWNER = "playbooks";
|
|
47
|
-
const LIMITS = { defaultTimeoutMs: 5_000, maxTimeoutMs: 30_000, maxRequestBytes: 65_536, maxResponseBytes: 262_144 };
|
|
48
46
|
|
|
49
47
|
export interface PlaybooksVehicleDeps {
|
|
50
48
|
artifacts: ArtifactStore;
|
|
@@ -70,7 +68,7 @@ export function registerPlaybooksVehicleOperations(registry: VehicleRegistry, de
|
|
|
70
68
|
/**
|
|
71
69
|
* Every playbooks.* action funnels through here. invoke's own module handler re-runs
|
|
72
70
|
* sessionIdentity.assertAuthorized directly (see this file's own doc comment) and its
|
|
73
|
-
* blueprint-materialization engine (workflow-execution.ts) can hit the same execution-graph
|
|
71
|
+
* blueprint-materialization engine (playbook/workflow-execution.ts) can hit the same execution-graph
|
|
74
72
|
* bounds tasks-vehicle.ts's own operations do -- classifying both reviewed domain error classes
|
|
75
73
|
* at this one choke point covers every action that can throw them. Anything else propagates
|
|
76
74
|
* unchanged -- vehicle-registry's own secure-by-default handler-failed opacity still applies to a
|
|
@@ -80,36 +78,7 @@ export function registerPlaybooksVehicleOperations(registry: VehicleRegistry, de
|
|
|
80
78
|
classifySessionAuthorization(() =>
|
|
81
79
|
classifyTaskExecutionBounds(() => classifyPlaybookComposition(() => moduleOperations.get(name)!.execute(input))),
|
|
82
80
|
);
|
|
83
|
-
|
|
84
|
-
const define = (
|
|
85
|
-
action: string,
|
|
86
|
-
description: string,
|
|
87
|
-
effect: "read" | "local-write",
|
|
88
|
-
properties: Record<string, { type: string; enum?: readonly string[] }>,
|
|
89
|
-
required: readonly string[],
|
|
90
|
-
resolve: (input: Record<string, unknown>) => Record<string, unknown>,
|
|
91
|
-
execute?: (input: Record<string, unknown>, context: VehicleOperationContext<Record<string, unknown>>) => unknown,
|
|
92
|
-
): void => {
|
|
93
|
-
const operation = defineVehicleOperation({
|
|
94
|
-
name: `playbooks.${action}`,
|
|
95
|
-
version: 1,
|
|
96
|
-
description,
|
|
97
|
-
input: looseObjectSchema(properties, required),
|
|
98
|
-
output: passthroughOutput,
|
|
99
|
-
permissions: ["playbooks:read", "playbooks:write"],
|
|
100
|
-
effect,
|
|
101
|
-
idempotency: { mode: effect === "read" ? "safe" : "unsafe" },
|
|
102
|
-
limits: LIMITS,
|
|
103
|
-
});
|
|
104
|
-
registry.register(
|
|
105
|
-
OWNER,
|
|
106
|
-
bindVehicleOperation(
|
|
107
|
-
operation,
|
|
108
|
-
() => async (context) =>
|
|
109
|
-
(execute ?? ((input: Record<string, unknown>) => call(`playbooks.${action}`, input)))(resolve(context.input), context),
|
|
110
|
-
),
|
|
111
|
-
);
|
|
112
|
-
};
|
|
81
|
+
const define = createOperationDefiner(registry, OWNER, "playbooks", ["playbooks:read", "playbooks:write"], call);
|
|
113
82
|
|
|
114
83
|
define(
|
|
115
84
|
"create",
|
|
@@ -242,10 +211,13 @@ export function registerPlaybooksVehicleOperations(registry: VehicleRegistry, de
|
|
|
242
211
|
(input) => ({ ...input, id: resolvePlaybookId(artifacts, artifactScopes, input.id, input.name) }),
|
|
243
212
|
);
|
|
244
213
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
214
|
+
const resolvePlaybookIdField = (input: Record<string, unknown>, idProp: string, nameProp: string): string =>
|
|
215
|
+
resolvePlaybookId(artifacts, artifactScopes, input[idProp], input[nameProp]);
|
|
216
|
+
|
|
217
|
+
definePairedMutation(
|
|
218
|
+
define,
|
|
219
|
+
{ idProp: "parent_id", nameProp: "parent_name" },
|
|
220
|
+
{ idProp: "child_id", nameProp: "child_name" },
|
|
249
221
|
{
|
|
250
222
|
parent_id: stringProp,
|
|
251
223
|
parent_name: stringProp,
|
|
@@ -256,38 +228,19 @@ export function registerPlaybooksVehicleOperations(registry: VehicleRegistry, de
|
|
|
256
228
|
session_id: stringProp,
|
|
257
229
|
},
|
|
258
230
|
[],
|
|
259
|
-
|
|
260
|
-
...input,
|
|
261
|
-
parent_id: resolvePlaybookId(artifacts, artifactScopes, input.parent_id, input.parent_name),
|
|
262
|
-
child_id: resolvePlaybookId(artifacts, artifactScopes, input.child_id, input.child_name),
|
|
263
|
-
}),
|
|
264
|
-
);
|
|
265
|
-
|
|
266
|
-
define(
|
|
267
|
-
"uncontain",
|
|
268
|
-
"Removes a parent/child Playbook nesting. Idempotent -- a no-op if the edge is already absent.",
|
|
269
|
-
"local-write",
|
|
231
|
+
resolvePlaybookIdField,
|
|
270
232
|
{
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
child_name: stringProp,
|
|
275
|
-
actor: stringProp,
|
|
276
|
-
source: stringProp,
|
|
277
|
-
session_id: stringProp,
|
|
233
|
+
action: "contain",
|
|
234
|
+
description:
|
|
235
|
+
"Nests a child Playbook inside a parent -- the child's steps run AFTER the parent's own. Prefer parent_name/child_name over parent_id/child_id -- resolved server-side.",
|
|
278
236
|
},
|
|
279
|
-
|
|
280
|
-
(input) => ({
|
|
281
|
-
...input,
|
|
282
|
-
parent_id: resolvePlaybookId(artifacts, artifactScopes, input.parent_id, input.parent_name),
|
|
283
|
-
child_id: resolvePlaybookId(artifacts, artifactScopes, input.child_id, input.child_name),
|
|
284
|
-
}),
|
|
237
|
+
{ action: "uncontain", description: "Removes a parent/child Playbook nesting. Idempotent -- a no-op if the edge is already absent." },
|
|
285
238
|
);
|
|
286
239
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
"
|
|
240
|
+
definePairedMutation(
|
|
241
|
+
define,
|
|
242
|
+
{ idProp: "id", nameProp: "name" },
|
|
243
|
+
{ idProp: "dependency_id", nameProp: "dependency_name" },
|
|
291
244
|
{
|
|
292
245
|
id: stringProp,
|
|
293
246
|
name: stringProp,
|
|
@@ -298,31 +251,12 @@ export function registerPlaybooksVehicleOperations(registry: VehicleRegistry, de
|
|
|
298
251
|
session_id: stringProp,
|
|
299
252
|
},
|
|
300
253
|
[],
|
|
301
|
-
|
|
302
|
-
...input,
|
|
303
|
-
id: resolvePlaybookId(artifacts, artifactScopes, input.id, input.name),
|
|
304
|
-
dependency_id: resolvePlaybookId(artifacts, artifactScopes, input.dependency_id, input.dependency_name),
|
|
305
|
-
}),
|
|
306
|
-
);
|
|
307
|
-
|
|
308
|
-
define(
|
|
309
|
-
"undepend",
|
|
310
|
-
"Removes a Playbook dependency. Idempotent -- a no-op if the edge is already absent.",
|
|
311
|
-
"local-write",
|
|
254
|
+
resolvePlaybookIdField,
|
|
312
255
|
{
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
dependency_name: stringProp,
|
|
317
|
-
actor: stringProp,
|
|
318
|
-
source: stringProp,
|
|
319
|
-
session_id: stringProp,
|
|
256
|
+
action: "depend",
|
|
257
|
+
description:
|
|
258
|
+
"Chains a prerequisite Playbook before another -- it must fully complete FIRST. Prefer dependency_name over dependency_id.",
|
|
320
259
|
},
|
|
321
|
-
|
|
322
|
-
(input) => ({
|
|
323
|
-
...input,
|
|
324
|
-
id: resolvePlaybookId(artifacts, artifactScopes, input.id, input.name),
|
|
325
|
-
dependency_id: resolvePlaybookId(artifacts, artifactScopes, input.dependency_id, input.dependency_name),
|
|
326
|
-
}),
|
|
260
|
+
{ action: "undepend", description: "Removes a Playbook dependency. Idempotent -- a no-op if the edge is already absent." },
|
|
327
261
|
);
|
|
328
262
|
}
|
|
@@ -6,23 +6,23 @@
|
|
|
6
6
|
* per domain.
|
|
7
7
|
*/
|
|
8
8
|
import { VehicleRegistry } from "@danypops/vehicle-server";
|
|
9
|
+
import type { ArtifactScopeStore } from "../artifact/artifact-scope-store.ts";
|
|
10
|
+
import type { ArtifactStore } from "../artifact/artifact-store.ts";
|
|
11
|
+
import type { ArtifactTrashStore } from "../artifact/artifact-trash-store.ts";
|
|
9
12
|
import type { AuthorityRegistry } from "../authority-registry.ts";
|
|
10
|
-
import type { Discussions } from "../discussion-service.ts";
|
|
11
|
-
import type { Notes } from "../note-service.ts";
|
|
12
|
-
import type {
|
|
13
|
-
import type {
|
|
14
|
-
import type {
|
|
15
|
-
import type {
|
|
16
|
-
import
|
|
17
|
-
import
|
|
18
|
-
import
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import { registerPlaybooksVehicleOperations } from "./playbooks-vehicle.ts";
|
|
24
|
-
import { registerRulesVehicleOperations } from "./rules-vehicle.ts";
|
|
25
|
-
import { registerTasksVehicleOperations } from "./tasks-vehicle.ts";
|
|
13
|
+
import type { Discussions } from "../discussion/discussion-service.ts";
|
|
14
|
+
import type { Notes } from "../note/note-service.ts";
|
|
15
|
+
import type { SessionIdentity } from "../session-identity/session-identity-service.ts";
|
|
16
|
+
import type { TaskEventStore } from "../stores/task-event-store.ts";
|
|
17
|
+
import type { TaskScopeStore } from "../stores/task-scope-store.ts";
|
|
18
|
+
import type { Tasks } from "../task/task-service.ts";
|
|
19
|
+
import { registerArtifactTrashOperations } from "./artifact-trash.ts";
|
|
20
|
+
import { registerDiscussVehicleOperations } from "./discuss.ts";
|
|
21
|
+
import { registerDocsVehicleOperations } from "./docs.ts";
|
|
22
|
+
import { registerNotesVehicleOperations } from "./notes.ts";
|
|
23
|
+
import { registerPlaybooksVehicleOperations } from "./playbooks.ts";
|
|
24
|
+
import { registerRulesVehicleOperations } from "./rules.ts";
|
|
25
|
+
import { registerTasksVehicleOperations } from "./tasks.ts";
|
|
26
26
|
|
|
27
27
|
export interface PapyrusVehicleDeps {
|
|
28
28
|
artifacts: ArtifactStore & ArtifactTrashStore;
|