@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.
Files changed (93) hide show
  1. package/package.json +3 -2
  2. package/src/{ports → artifact}/artifact-event-reader.ts +1 -1
  3. package/src/{artifact-relationship-view.ts → artifact/artifact-relationship-view.ts} +3 -3
  4. package/src/{ports → artifact}/artifact-store.ts +2 -2
  5. package/src/{artifact-subtree.ts → artifact/artifact-subtree.ts} +4 -4
  6. package/src/{ports → artifact}/artifact-trash-store.ts +2 -2
  7. package/src/{adapters → artifact}/sqlite-artifact-scope-store.ts +1 -1
  8. package/src/{adapters → artifact}/sqlite-artifact-store.ts +15 -15
  9. package/src/authority-registry.ts +3 -3
  10. package/src/cli/artifact-command.ts +210 -0
  11. package/src/cli/discuss-command.ts +256 -0
  12. package/src/cli/docs-command.ts +192 -0
  13. package/src/cli/gates-command.ts +46 -0
  14. package/src/cli/graph-command.ts +171 -0
  15. package/src/cli/graph-projection-command.ts +79 -0
  16. package/src/cli/log-command.ts +101 -0
  17. package/src/cli/migration-command.ts +40 -0
  18. package/src/cli/note-command.ts +186 -0
  19. package/src/cli/playbooks-command.ts +313 -0
  20. package/src/cli/rules-command.ts +220 -0
  21. package/src/cli/session-identity-command.ts +58 -0
  22. package/src/cli/shared.ts +5 -0
  23. package/src/cli/stricli-run.ts +30 -0
  24. package/src/cli/task-command.ts +892 -0
  25. package/src/cli.ts +32 -1914
  26. package/src/client.ts +2 -2
  27. package/src/{daemon-state.ts → daemon/daemon-state.ts} +1 -1
  28. package/src/{daemon.ts → daemon/daemon.ts} +3 -3
  29. package/src/db.ts +1 -1
  30. package/src/{discussion-service.ts → discussion/discussion-service.ts} +7 -6
  31. package/src/domain-services.ts +5 -5
  32. package/src/{graph-projection-service.ts → graph-projection/graph-projection-service.ts} +6 -6
  33. package/src/{vehicle/artifact-trash-vehicle.ts → handlers/artifact-trash.ts} +4 -4
  34. package/src/{vehicle/discuss-vehicle.ts → handlers/discuss.ts} +20 -25
  35. package/src/{vehicle/docs-vehicle.ts → handlers/docs.ts} +4 -37
  36. package/src/{vehicle/notes-vehicle.ts → handlers/notes.ts} +4 -38
  37. package/src/{vehicle/playbooks-vehicle.ts → handlers/playbooks.ts} +34 -100
  38. package/src/{vehicle/papyrus-vehicle.ts → handlers/registry.ts} +16 -16
  39. package/src/{vehicle/rules-vehicle.ts → handlers/rules.ts} +4 -37
  40. package/src/{vehicle/artifact-vehicle-shared.ts → handlers/shared.ts} +96 -6
  41. package/src/{vehicle/tasks-vehicle.ts → handlers/tasks.ts} +37 -124
  42. package/src/index.ts +13 -13
  43. package/src/{log-service.ts → log/log-service.ts} +2 -2
  44. package/src/modules/discuss.ts +7 -28
  45. package/src/modules/docs.ts +4 -24
  46. package/src/modules/graph-projection.ts +5 -11
  47. package/src/modules/logs.ts +2 -23
  48. package/src/modules/notes.ts +2 -23
  49. package/src/modules/operation-input.ts +35 -0
  50. package/src/modules/playbooks.ts +13 -33
  51. package/src/modules/rules.ts +4 -24
  52. package/src/modules/session-identity.ts +2 -16
  53. package/src/modules/tasks.ts +11 -38
  54. package/src/{note-service.ts → note/note-service.ts} +6 -6
  55. package/src/ops.ts +6 -6
  56. package/src/{playbook-definition.ts → playbook/playbook-definition.ts} +7 -6
  57. package/src/{playbook-execution.ts → playbook/playbook-execution.ts} +5 -4
  58. package/src/{workflow-execution.ts → playbook/workflow-execution.ts} +12 -12
  59. package/src/service.ts +30 -57
  60. package/src/{session-identity-service.ts → session-identity/session-identity-service.ts} +2 -2
  61. package/src/{ports → stores}/session-identity-store.ts +1 -1
  62. package/src/{adapters → stores}/sqlite-discussion-round-store.ts +1 -1
  63. package/src/{adapters → stores}/sqlite-gate-runner.ts +1 -1
  64. package/src/{adapters → stores}/sqlite-graph-projection-store.ts +1 -1
  65. package/src/{adapters → stores}/sqlite-log-store.ts +1 -1
  66. package/src/{adapters → stores}/sqlite-note-event-store.ts +1 -1
  67. package/src/{adapters → stores}/sqlite-session-identity-store.ts +1 -1
  68. package/src/{adapters → stores}/sqlite-task-event-store.ts +1 -1
  69. package/src/{adapters → stores}/sqlite-task-focus-store.ts +1 -1
  70. package/src/{adapters → stores}/sqlite-task-lease-store.ts +1 -1
  71. package/src/{adapters → stores}/sqlite-task-scope-store.ts +1 -1
  72. package/src/{task-context.ts → task/task-context.ts} +4 -4
  73. package/src/{task-execution.ts → task/task-execution.ts} +1 -1
  74. package/src/{task-graph-view.ts → task/task-graph-view.ts} +1 -1
  75. package/src/{task-relationship-view.ts → task/task-relationship-view.ts} +3 -3
  76. package/src/{task-service.ts → task/task-service.ts} +14 -14
  77. /package/src/{domain → artifact}/artifact-alias.ts +0 -0
  78. /package/src/{domain → artifact}/artifact-event.ts +0 -0
  79. /package/src/{ports → artifact}/artifact-scope-store.ts +0 -0
  80. /package/src/{domain → artifact}/artifact-trash.ts +0 -0
  81. /package/src/{domain → artifact}/artifact.ts +0 -0
  82. /package/src/{ports → artifact}/atomic-artifact-store.ts +0 -0
  83. /package/src/{log.ts → log/log.ts} +0 -0
  84. /package/src/{ports → stores}/discussion-round-store.ts +0 -0
  85. /package/src/{ports → stores}/gate-runner.ts +0 -0
  86. /package/src/{ports → stores}/graph-projection-store.ts +0 -0
  87. /package/src/{ports → stores}/graph-renderer.ts +0 -0
  88. /package/src/{ports → stores}/log-store.ts +0 -0
  89. /package/src/{ports → stores}/note-event-store.ts +0 -0
  90. /package/src/{ports → stores}/task-event-store.ts +0 -0
  91. /package/src/{ports → stores}/task-focus-store.ts +0 -0
  92. /package/src/{ports → stores}/task-lease-store.ts +0 -0
  93. /package/src/{ports → stores}/task-scope-store.ts +0 -0
@@ -15,32 +15,11 @@
15
15
 
16
16
  import type { NoteEventDirection } from "../domain/note-event.ts";
17
17
  import type { OperationDefinition } from "../module-registry.ts";
18
- import type { NoteDisposition, Notes } from "../note-service.ts";
18
+ import type { NoteDisposition, Notes } from "../note/note-service.ts";
19
+ import { type OperationInput, optionalNumber, optionalString, string } from "./operation-input.ts";
19
20
 
20
21
  const MODULE_ID = "notes";
21
22
 
22
- type OperationInput = Record<string, unknown>;
23
-
24
- function string(input: OperationInput, key: string): string {
25
- const value = input[key];
26
- if (typeof value !== "string" || value.length === 0) throw new Error(`${key} is required`);
27
- return value;
28
- }
29
-
30
- function optionalString(input: OperationInput, key: string): string | undefined {
31
- const value = input[key];
32
- if (value === undefined) return undefined;
33
- if (typeof value !== "string") throw new Error(`${key} must be a string`);
34
- return value;
35
- }
36
-
37
- function optionalNumber(input: OperationInput, key: string): number | undefined {
38
- const value = input[key];
39
- if (value === undefined) return undefined;
40
- if (typeof value !== "number" || !Number.isFinite(value)) throw new Error(`${key} must be a number`);
41
- return value;
42
- }
43
-
44
23
  /** This module's own operation names, the single source of truth src/service.ts's EXPECTED_OPERATION_NAMES spreads in rather than re-listing by hand. */
45
24
  export const NOTES_OPERATION_NAMES = [
46
25
  "notes.capture",
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Shared runtime validators for a Vehicle operation's raw `input` object.
3
+ * A Vehicle operation's own JSON-schema `input` field is descriptive metadata
4
+ * only (see handlers/shared.ts's looseObjectSchema) -- never itself enforced
5
+ * at runtime -- so every module's own operation body narrows `unknown` to
6
+ * the real shape it needs through these.
7
+ */
8
+ export type OperationInput = Record<string, unknown>;
9
+
10
+ export function string(input: OperationInput, key: string): string {
11
+ const value = input[key];
12
+ if (typeof value !== "string" || value.length === 0) throw new Error(`${key} is required`);
13
+ return value;
14
+ }
15
+
16
+ export function optionalString(input: OperationInput, key: string): string | undefined {
17
+ const value = input[key];
18
+ if (value === undefined) return undefined;
19
+ if (typeof value !== "string") throw new Error(`${key} must be a string`);
20
+ return value;
21
+ }
22
+
23
+ export function optionalStringArray(input: OperationInput, key: string): string[] | undefined {
24
+ const value = input[key];
25
+ if (value === undefined) return undefined;
26
+ if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string")) throw new Error(`${key} must be an array of strings`);
27
+ return value as string[];
28
+ }
29
+
30
+ export function optionalNumber(input: OperationInput, key: string): number | undefined {
31
+ const value = input[key];
32
+ if (value === undefined) return undefined;
33
+ if (typeof value !== "number" || !Number.isFinite(value)) throw new Error(`${key} must be a number`);
34
+ return value;
35
+ }
@@ -4,11 +4,14 @@
4
4
  * A Playbook is prose-first, whole-artifact composition (contains/depends_on between real
5
5
  * Playbook artifacts) rather than a raw JSON blueprint -- but its own step list can also
6
6
  * declare Doc/Rule blueprints and typed arguments and nested pipeline calls. playbooks.invoke
7
- * recycles the shared blueprint materialization engine (playbook-execution.ts compiles a
7
+ * recycles the shared blueprint materialization engine (playbook/playbook-execution.ts compiles a
8
8
  * Playbook's steps and composition tree into a BlueprintDefinition, then hands off to
9
- * workflow-execution.ts's shared core). See domain-services.ts's Playbook section and
10
- * playbook-definition.ts for the full rationale.
9
+ * playbook/workflow-execution.ts's shared core). See domain-services.ts's Playbook section and
10
+ * playbook/playbook-definition.ts for the full rationale.
11
11
  */
12
+
13
+ import type { ArtifactScopeStore } from "../artifact/artifact-scope-store.ts";
14
+ import type { ArtifactStore } from "../artifact/artifact-store.ts";
12
15
  import {
13
16
  assignPlaybookProject,
14
17
  containPlaybook,
@@ -23,38 +26,15 @@ import {
23
26
  updatePlaybook,
24
27
  } from "../domain-services.ts";
25
28
  import type { OperationDefinition } from "../module-registry.ts";
26
- import { invokePlaybook } from "../playbook-execution.ts";
27
- import type { ArtifactScopeStore } from "../ports/artifact-scope-store.ts";
28
- import type { ArtifactStore } from "../ports/artifact-store.ts";
29
- import type { TaskEventStore } from "../ports/task-event-store.ts";
30
- import type { TaskScopeStore } from "../ports/task-scope-store.ts";
31
- import type { SessionIdentity } from "../session-identity-service.ts";
32
- import type { Tasks } from "../task-service.ts";
29
+ import { invokePlaybook } from "../playbook/playbook-execution.ts";
30
+ import type { SessionIdentity } from "../session-identity/session-identity-service.ts";
31
+ import type { TaskEventStore } from "../stores/task-event-store.ts";
32
+ import type { TaskScopeStore } from "../stores/task-scope-store.ts";
33
+ import type { Tasks } from "../task/task-service.ts";
34
+ import { type OperationInput, optionalNumber, optionalString, string } from "./operation-input.ts";
33
35
 
34
36
  const MODULE_ID = "playbooks";
35
37
 
36
- type OperationInput = Record<string, unknown>;
37
-
38
- function string(input: OperationInput, key: string): string {
39
- const value = input[key];
40
- if (typeof value !== "string" || value.length === 0) throw new Error(`${key} is required`);
41
- return value;
42
- }
43
-
44
- function optionalString(input: OperationInput, key: string): string | undefined {
45
- const value = input[key];
46
- if (value === undefined) return undefined;
47
- if (typeof value !== "string") throw new Error(`${key} must be a string`);
48
- return value;
49
- }
50
-
51
- function optionalNumber(input: OperationInput, key: string): number | undefined {
52
- const value = input[key];
53
- if (value === undefined) return undefined;
54
- if (typeof value !== "number" || !Number.isFinite(value)) throw new Error(`${key} must be a number`);
55
- return value;
56
- }
57
-
58
38
  const eventContext = (input: OperationInput) => ({
59
39
  actor: optionalString(input, "actor"),
60
40
  source: optionalString(input, "source"),
@@ -96,7 +76,7 @@ export interface PlaybooksModuleDeps {
96
76
  scopes: TaskScopeStore;
97
77
  /** Docs/Rules/Skills/Playbooks project scoping (distinct from `scopes`, which is Task-run project scoping for playbooks.invoke's materialized tasks). */
98
78
  artifactScopes: ArtifactScopeStore;
99
- /** Used for exactly one thing: focusing the entry task after a successful invoke -- the one safety-checked Tasks operation this module needs, not bulk graph construction (that goes straight through artifacts/events/scopes in playbook-execution.ts, mirroring workflow-execution.ts). */
79
+ /** Used for exactly one thing: focusing the entry task after a successful invoke -- the one safety-checked Tasks operation this module needs, not bulk graph construction (that goes straight through artifacts/events/scopes in playbook/playbook-execution.ts, mirroring playbook/workflow-execution.ts). */
100
80
  tasks: Tasks;
101
81
  /** Guards the same session_secret check tasks.focus's own operation enforces (guardFocusMutation in modules/tasks.ts) -- invoke's internal tasks.focus() call goes straight through the Tasks class, bypassing that operation wrapper entirely, so the check must be applied here instead of silently skipped. */
102
82
  sessionIdentity: SessionIdentity;
@@ -10,6 +10,9 @@
10
10
  * into this module or introducing a premature "modules call each other through the
11
11
  * registry" convention.
12
12
  */
13
+
14
+ import type { ArtifactScopeStore } from "../artifact/artifact-scope-store.ts";
15
+ import type { ArtifactStore } from "../artifact/artifact-store.ts";
13
16
  import {
14
17
  assignRuleProject,
15
18
  createRule,
@@ -21,33 +24,10 @@ import {
21
24
  updateRule,
22
25
  } from "../domain-services.ts";
23
26
  import type { OperationDefinition } from "../module-registry.ts";
24
- import type { ArtifactScopeStore } from "../ports/artifact-scope-store.ts";
25
- import type { ArtifactStore } from "../ports/artifact-store.ts";
27
+ import { type OperationInput, optionalNumber, optionalString, string } from "./operation-input.ts";
26
28
 
27
29
  const MODULE_ID = "rules";
28
30
 
29
- type OperationInput = Record<string, unknown>;
30
-
31
- function string(input: OperationInput, key: string): string {
32
- const value = input[key];
33
- if (typeof value !== "string" || value.length === 0) throw new Error(`${key} is required`);
34
- return value;
35
- }
36
-
37
- function optionalString(input: OperationInput, key: string): string | undefined {
38
- const value = input[key];
39
- if (value === undefined) return undefined;
40
- if (typeof value !== "string") throw new Error(`${key} must be a string`);
41
- return value;
42
- }
43
-
44
- function optionalNumber(input: OperationInput, key: string): number | undefined {
45
- const value = input[key];
46
- if (value === undefined) return undefined;
47
- if (typeof value !== "number" || !Number.isFinite(value)) throw new Error(`${key} must be a number`);
48
- return value;
49
- }
50
-
51
31
  const eventContext = (input: OperationInput) => ({
52
32
  actor: optionalString(input, "actor"),
53
33
  source: optionalString(input, "source"),
@@ -4,25 +4,11 @@
4
4
  * precedent set by modules/logs.ts. See domain/session-identity.ts for the design rationale.
5
5
  */
6
6
  import type { OperationDefinition } from "../module-registry.ts";
7
- import type { SessionIdentity } from "../session-identity-service.ts";
7
+ import type { SessionIdentity } from "../session-identity/session-identity-service.ts";
8
+ import { type OperationInput, optionalString, string } from "./operation-input.ts";
8
9
 
9
10
  const MODULE_ID = "session-identity";
10
11
 
11
- type OperationInput = Record<string, unknown>;
12
-
13
- function string(input: OperationInput, key: string): string {
14
- const value = input[key];
15
- if (typeof value !== "string" || value.length === 0) throw new Error(`${key} is required`);
16
- return value;
17
- }
18
-
19
- function optionalString(input: OperationInput, key: string): string | undefined {
20
- const value = input[key];
21
- if (value === undefined) return undefined;
22
- if (typeof value !== "string") throw new Error(`${key} must be a string`);
23
- return value;
24
- }
25
-
26
12
  /** This module's own operation names, the single source of truth src/service.ts's EXPECTED_OPERATION_NAMES spreads in rather than re-listing by hand. */
27
13
  export const SESSION_IDENTITY_OPERATION_NAMES = ["session.register", "session.release"] as const;
28
14
 
@@ -13,52 +13,25 @@
13
13
  *
14
14
  * Task-domain-internal files (task-context.ts, task-execution.ts, domain/task-event.ts,
15
15
  * domain/task-scope.ts) are imported directly — they belong to this bounded context,
16
- * unlike a different module's infrastructure. Generic input-parsing helpers are
17
- * duplicated locally rather than imported from src/service.ts, matching the precedent
18
- * set by modules/notes.ts: a module does not import another module's infrastructure,
19
- * including the composition root's own helpers.
16
+ * unlike a different module's infrastructure. Generic input-parsing helpers come from
17
+ * ./operation-input.ts, a peer utility at this same modules/ layer with no domain logic
18
+ * of its own -- not "another module's infrastructure" or the composition root's helpers,
19
+ * the actual thing this module avoids importing.
20
20
  */
21
+
22
+ import type { ArtifactStore } from "../artifact/artifact-store.ts";
21
23
  import type { Checklist } from "../domain/checklist.ts";
22
24
  import type { TaskEventContext, TaskEventDirection, TaskEventFeedQuery } from "../domain/task-event.ts";
23
25
  import type { TaskViewMode } from "../domain/task-scope.ts";
24
26
  import type { OperationDefinition } from "../module-registry.ts";
25
- import type { ArtifactStore } from "../ports/artifact-store.ts";
26
- import type { SessionIdentity } from "../session-identity-service.ts";
27
- import { taskContext } from "../task-context.ts";
28
- import { projectTaskExecution } from "../task-execution.ts";
29
- import type { TaskStatus, Tasks } from "../task-service.ts";
27
+ import type { SessionIdentity } from "../session-identity/session-identity-service.ts";
28
+ import { taskContext } from "../task/task-context.ts";
29
+ import { projectTaskExecution } from "../task/task-execution.ts";
30
+ import type { TaskStatus, Tasks } from "../task/task-service.ts";
31
+ import { type OperationInput, optionalNumber, optionalString, optionalStringArray, string } from "./operation-input.ts";
30
32
 
31
33
  const MODULE_ID = "tasks";
32
34
 
33
- type OperationInput = Record<string, unknown>;
34
-
35
- function string(input: OperationInput, key: string): string {
36
- const value = input[key];
37
- if (typeof value !== "string" || value.length === 0) throw new Error(`${key} is required`);
38
- return value;
39
- }
40
-
41
- function optionalString(input: OperationInput, key: string): string | undefined {
42
- const value = input[key];
43
- if (value === undefined) return undefined;
44
- if (typeof value !== "string") throw new Error(`${key} must be a string`);
45
- return value;
46
- }
47
-
48
- function optionalStringArray(input: OperationInput, key: string): string[] | undefined {
49
- const value = input[key];
50
- if (value === undefined) return undefined;
51
- if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string")) throw new Error(`${key} must be an array of strings`);
52
- return value as string[];
53
- }
54
-
55
- function optionalNumber(input: OperationInput, key: string): number | undefined {
56
- const value = input[key];
57
- if (value === undefined) return undefined;
58
- if (typeof value !== "number" || !Number.isFinite(value)) throw new Error(`${key} must be a number`);
59
- return value;
60
- }
61
-
62
35
  const eventContext = (input: OperationInput): TaskEventContext => ({
63
36
  actor: optionalString(input, "actor"),
64
37
  source: optionalString(input, "source"),
@@ -1,3 +1,6 @@
1
+ import type { Artifact } from "../artifact/artifact.ts";
2
+ import type { ArtifactStore } from "../artifact/artifact-store.ts";
3
+ import { requireAtomicArtifactStore } from "../artifact/atomic-artifact-store.ts";
1
4
  import {
2
5
  NOTE_BODY_MAX_CHARACTERS,
3
6
  NOTE_LIST_DEFAULT_LIMIT,
@@ -6,12 +9,9 @@ import {
6
9
  NOTE_REASON_MAX_CHARACTERS,
7
10
  NOTE_TITLE_MAX_CHARACTERS,
8
11
  TASK_PROJECT_ROOT_MAX_LENGTH,
9
- } from "./constants.ts";
10
- import type { Artifact } from "./domain/artifact.ts";
11
- import type { AppendNoteEvent, NoteEventType, NoteHistoryPage, NoteHistoryQuery } from "./domain/note-event.ts";
12
- import type { ArtifactStore } from "./ports/artifact-store.ts";
13
- import { requireAtomicArtifactStore } from "./ports/atomic-artifact-store.ts";
14
- import { InMemoryNoteEventStore, type NoteEventStore } from "./ports/note-event-store.ts";
12
+ } from "../constants.ts";
13
+ import type { AppendNoteEvent, NoteEventType, NoteHistoryPage, NoteHistoryQuery } from "../domain/note-event.ts";
14
+ import { InMemoryNoteEventStore, type NoteEventStore } from "../stores/note-event-store.ts";
15
15
 
16
16
  export const NOTE_SUBTYPE = "note";
17
17
  export const NOTE_DISPOSITIONS = ["completed", "duplicate", "declined", "superseded"] as const;
package/src/ops.ts CHANGED
@@ -3,14 +3,14 @@
3
3
  * Enforces the schema protocol (kinds, statuses, relations) via FK + app validation.
4
4
  */
5
5
  import { createRequire } from "node:module";
6
+ import type { Artifact, ArtifactQuery, CreateArtifactInput, UpdateArtifactInput } from "./artifact/artifact.ts";
7
+ import { generateUniqueAlias, isValidAlias, slugify } from "./artifact/artifact-alias.ts";
8
+ import type { ArtifactTrashRecord } from "./artifact/artifact-trash.ts";
6
9
  import { ARTIFACT_TRASH_RETENTION_MS, DEFAULT_STATUS_BY_KIND } from "./constants.ts";
7
10
  import type { Db } from "./db.ts";
8
11
  import { inTransaction } from "./db.ts";
9
- import type { Artifact, ArtifactQuery, CreateArtifactInput, UpdateArtifactInput } from "./domain/artifact.ts";
10
- import { generateUniqueAlias, isValidAlias, slugify } from "./domain/artifact-alias.ts";
11
- import type { ArtifactTrashRecord } from "./domain/artifact-trash.ts";
12
12
 
13
- export type { ArtifactTrashRecord } from "./domain/artifact-trash.ts";
13
+ export type { ArtifactTrashRecord } from "./artifact/artifact-trash.ts";
14
14
 
15
15
  import {
16
16
  type AppendArtifactEvent,
@@ -21,10 +21,10 @@ import {
21
21
  type ArtifactEventType,
22
22
  normalizeArtifactEventQuery,
23
23
  resolveArtifactEvent,
24
- } from "./domain/artifact-event.ts";
24
+ } from "./artifact/artifact-event.ts";
25
25
  import type { Gate, GateResult, GateRunOptions } from "./domain/gate.ts";
26
26
 
27
- export type { Artifact } from "./domain/artifact.ts";
27
+ export type { Artifact } from "./artifact/artifact.ts";
28
28
  export type { Gate, GateResult } from "./domain/gate.ts";
29
29
  export type CreateInput = CreateArtifactInput;
30
30
 
@@ -18,12 +18,14 @@
18
18
  * independently by workflow-execution.ts, exactly like a workflow-definition target's own
19
19
  * nested pipeline step, since its target's own definition is not knowable at this compile time.
20
20
  */
21
+
22
+ import type { Artifact } from "../artifact/artifact.ts";
23
+ import type { ArtifactStore } from "../artifact/artifact-store.ts";
21
24
  import {
22
25
  PLAYBOOK_INVOCATION_MAX_CALL_DEPTH,
23
26
  PLAYBOOK_INVOCATION_MAX_CREATED_TASKS,
24
27
  PLAYBOOK_INVOCATION_MAX_LINKED_ARTIFACTS,
25
- } from "./constants.ts";
26
- import type { Artifact } from "./domain/artifact.ts";
28
+ } from "../constants.ts";
27
29
  import type {
28
30
  BlueprintDefinition,
29
31
  BlueprintInputDefinition,
@@ -31,10 +33,9 @@ import type {
31
33
  DocBlueprint,
32
34
  RuleBlueprint,
33
35
  TaskBlueprint,
34
- } from "./domain/blueprint-definition.ts";
35
- import { validateBlueprintDefinition } from "./domain/blueprint-definition.ts";
36
- import type { PlaybookArgument, PlaybookStep } from "./domain-services.ts";
37
- import type { ArtifactStore } from "./ports/artifact-store.ts";
36
+ } from "../domain/blueprint-definition.ts";
37
+ import { validateBlueprintDefinition } from "../domain/blueprint-definition.ts";
38
+ import type { PlaybookArgument, PlaybookStep } from "../domain-services.ts";
38
39
 
39
40
  /** A non-composing edge touching a playbook node, to be mirrored onto that node's generated root task once real task ids exist -- e.g. a Rule `gates` this playbook, or this playbook `references`/`documents` a Doc. Direction is preserved exactly: `from`/`to` name whichever side is NOT the playbook, and `ownerIsFrom` says which side the playbook (now the generated root task) occupies. */
40
41
  export interface PlaybookExternalLink {
@@ -7,11 +7,12 @@
7
7
  * (via the existing Task Focus system-prompt pointer), which is what actually avoids the
8
8
  * old text-dump problem: one page at a time, not the whole book at once.
9
9
  */
10
- import type { BlueprintArgumentValue } from "./domain/blueprint-definition.ts";
10
+
11
+ import type { ArtifactStore } from "../artifact/artifact-store.ts";
12
+ import { requireAtomicArtifactStore } from "../artifact/atomic-artifact-store.ts";
13
+ import type { BlueprintArgumentValue } from "../domain/blueprint-definition.ts";
14
+ import type { TaskExecutionPlan } from "../task/task-execution.ts";
11
15
  import { compilePlaybookDefinition } from "./playbook-definition.ts";
12
- import type { ArtifactStore } from "./ports/artifact-store.ts";
13
- import { requireAtomicArtifactStore } from "./ports/atomic-artifact-store.ts";
14
- import type { TaskExecutionPlan } from "./task-execution.ts";
15
16
  import {
16
17
  applyPlaybookExternalLinks,
17
18
  materializeWorkflowDefinition,
@@ -1,28 +1,28 @@
1
1
  import { randomUUID } from "node:crypto";
2
+ import type { Artifact } from "../artifact/artifact.ts";
3
+ import type { ArtifactStore } from "../artifact/artifact-store.ts";
4
+ import { requireAtomicArtifactStore } from "../artifact/atomic-artifact-store.ts";
2
5
  import {
3
6
  SKILL_MAX_RENDERED_BYTES,
4
7
  SKILL_RUN_ID_MAX_LENGTH,
5
8
  SKILL_WORKFLOW_MAX_NESTING_DEPTH,
6
9
  TASK_EXECUTION_MAX_EDGES,
7
- } from "./constants.ts";
8
- import type { Artifact } from "./domain/artifact.ts";
10
+ } from "../constants.ts";
9
11
  import {
10
12
  type BlueprintArgumentValue,
11
13
  type BlueprintDefinition,
12
14
  type CallBlueprint,
13
15
  resolveBlueprintArguments,
14
16
  validateBlueprintDefinition,
15
- } from "./domain/blueprint-definition.ts";
16
- import { validateChecklist } from "./domain/checklist.ts";
17
- import type { TaskEventContext } from "./domain/task-event.ts";
18
- import { normalizeProjectRoot } from "./domain/task-scope.ts";
17
+ } from "../domain/blueprint-definition.ts";
18
+ import { validateChecklist } from "../domain/checklist.ts";
19
+ import type { TaskEventContext } from "../domain/task-event.ts";
20
+ import { normalizeProjectRoot } from "../domain/task-scope.ts";
21
+ import type { TaskEventStore } from "../stores/task-event-store.ts";
22
+ import type { TaskScopeStore } from "../stores/task-scope-store.ts";
23
+ import { projectTaskExecution, TaskExecutionBoundExceededError, type TaskExecutionPlan } from "../task/task-execution.ts";
24
+ import type { TaskGraph, TaskNode, TaskStatus } from "../task/task-service.ts";
19
25
  import { compilePlaybookDefinition, type PlaybookExternalLink } from "./playbook-definition.ts";
20
- import type { ArtifactStore } from "./ports/artifact-store.ts";
21
- import { requireAtomicArtifactStore } from "./ports/atomic-artifact-store.ts";
22
- import type { TaskEventStore } from "./ports/task-event-store.ts";
23
- import type { TaskScopeStore } from "./ports/task-scope-store.ts";
24
- import { projectTaskExecution, TaskExecutionBoundExceededError, type TaskExecutionPlan } from "./task-execution.ts";
25
- import type { TaskGraph, TaskNode, TaskStatus } from "./task-service.ts";
26
26
 
27
27
  const RUN_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_-]*$/;
28
28
  const EXACT_PLACEHOLDER_PATTERN = /^{{\s*([A-Za-z][A-Za-z0-9_-]{0,63})\s*}}$/;
package/src/service.ts CHANGED
@@ -2,49 +2,50 @@ import { VehicleError } from "@danypops/vehicle-core";
2
2
  import type { VehicleRegistry } from "@danypops/vehicle-server";
3
3
  import { createVehicleHttpApp } from "@danypops/vehicle-server/http";
4
4
  import type { Logger } from "@danypops/vehicle-server/logging";
5
- import { SQLiteArtifactScopeStore } from "./adapters/sqlite-artifact-scope-store.ts";
6
- import { SQLiteArtifactStore } from "./adapters/sqlite-artifact-store.ts";
7
- import { SQLiteDiscussionRoundStore } from "./adapters/sqlite-discussion-round-store.ts";
8
- import { SQLiteGateRunner } from "./adapters/sqlite-gate-runner.ts";
9
- import { SQLiteGraphProjectionStore } from "./adapters/sqlite-graph-projection-store.ts";
10
- import { SQLiteLogStore } from "./adapters/sqlite-log-store.ts";
11
- import { SQLiteNoteEventStore } from "./adapters/sqlite-note-event-store.ts";
12
- import { SQLiteSessionIdentityStore } from "./adapters/sqlite-session-identity-store.ts";
13
- import { SQLiteTaskEventStore } from "./adapters/sqlite-task-event-store.ts";
14
- import { SQLiteTaskFocusStore } from "./adapters/sqlite-task-focus-store.ts";
15
- import { SQLiteTaskLeaseStore } from "./adapters/sqlite-task-lease-store.ts";
16
- import { SQLiteTaskScopeStore } from "./adapters/sqlite-task-scope-store.ts";
17
- import { removeArtifactSubtree } from "./artifact-subtree.ts";
5
+ import type { CreateArtifactInput } from "./artifact/artifact.ts";
6
+ import type { ArtifactEventReader } from "./artifact/artifact-event-reader.ts";
7
+ import type { ArtifactStore } from "./artifact/artifact-store.ts";
8
+ import { removeArtifactSubtree } from "./artifact/artifact-subtree.ts";
9
+ import type { ArtifactTrashStore } from "./artifact/artifact-trash-store.ts";
10
+ import { SQLiteArtifactScopeStore } from "./artifact/sqlite-artifact-scope-store.ts";
11
+ import { SQLiteArtifactStore } from "./artifact/sqlite-artifact-store.ts";
18
12
  import { type AuthorityClaim, AuthorityRegistry, AuthorizedArtifactWriter } from "./authority-registry.ts";
19
13
  import { SERVICE_MAX_BODY_BYTES, SQLITE_SCHEMA_VERSION } from "./constants.ts";
20
14
  import { migrateDb, openDb, schemaVersion } from "./db.ts";
21
- import { Discussions } from "./discussion-service.ts";
22
- import type { CreateArtifactInput } from "./domain/artifact.ts";
15
+ import { Discussions } from "./discussion/discussion-service.ts";
23
16
  import type { TaskEventContext } from "./domain/task-event.ts";
24
17
  import type { TaskViewMode } from "./domain/task-scope.ts";
25
18
  import { listInjectableRules } from "./domain-services.ts";
26
- import { logEvent } from "./log.ts";
27
- import { Logs } from "./log-service.ts";
19
+ import { createPapyrusVehicleRegistry } from "./handlers/registry.ts";
20
+ import { logEvent } from "./log/log.ts";
21
+ import { Logs } from "./log/log-service.ts";
28
22
  import { OperationRegistry } from "./module-registry.ts";
29
23
  import { DISCUSS_OPERATION_NAMES, discussOperations } from "./modules/discuss.ts";
30
24
  import { DOCS_OPERATION_NAMES, docsOperations } from "./modules/docs.ts";
31
25
  import { GRAPH_PROJECTION_OPERATION_NAMES, graphProjectionOperations } from "./modules/graph-projection.ts";
32
26
  import { LOGS_OPERATION_NAMES, logsOperations } from "./modules/logs.ts";
33
27
  import { NOTES_OPERATION_NAMES, notesOperations } from "./modules/notes.ts";
28
+ import { type OperationInput, optionalNumber, optionalString, string } from "./modules/operation-input.ts";
34
29
  import { PLAYBOOKS_OPERATION_NAMES, playbooksOperations } from "./modules/playbooks.ts";
35
30
  import { RULES_OPERATION_NAMES, rulesOperations } from "./modules/rules.ts";
36
31
  import { SESSION_IDENTITY_OPERATION_NAMES, sessionIdentityOperations } from "./modules/session-identity.ts";
37
32
  import { TASKS_OPERATION_NAMES, tasksOperations } from "./modules/tasks.ts";
38
- import { NOTE_SUBTYPE, Notes } from "./note-service.ts";
39
- import type { ArtifactEventReader } from "./ports/artifact-event-reader.ts";
40
- import type { ArtifactStore } from "./ports/artifact-store.ts";
41
- import type { ArtifactTrashStore } from "./ports/artifact-trash-store.ts";
42
- import type { GateRunner } from "./ports/gate-runner.ts";
43
- import type { TaskEventStore } from "./ports/task-event-store.ts";
44
- import type { TaskScopeStore } from "./ports/task-scope-store.ts";
45
- import { InvalidSessionSecretError, SessionIdentity } from "./session-identity-service.ts";
46
- import { type TaskStatus, Tasks } from "./task-service.ts";
47
- import { createPapyrusVehicleRegistry } from "./vehicle/papyrus-vehicle.ts";
33
+ import { NOTE_SUBTYPE, Notes } from "./note/note-service.ts";
34
+ import { InvalidSessionSecretError, SessionIdentity } from "./session-identity/session-identity-service.ts";
35
+ import type { GateRunner } from "./stores/gate-runner.ts";
36
+ import { SQLiteDiscussionRoundStore } from "./stores/sqlite-discussion-round-store.ts";
37
+ import { SQLiteGateRunner } from "./stores/sqlite-gate-runner.ts";
38
+ import { SQLiteGraphProjectionStore } from "./stores/sqlite-graph-projection-store.ts";
39
+ import { SQLiteLogStore } from "./stores/sqlite-log-store.ts";
40
+ import { SQLiteNoteEventStore } from "./stores/sqlite-note-event-store.ts";
41
+ import { SQLiteSessionIdentityStore } from "./stores/sqlite-session-identity-store.ts";
42
+ import { SQLiteTaskEventStore } from "./stores/sqlite-task-event-store.ts";
43
+ import { SQLiteTaskFocusStore } from "./stores/sqlite-task-focus-store.ts";
44
+ import { SQLiteTaskLeaseStore } from "./stores/sqlite-task-lease-store.ts";
45
+ import { SQLiteTaskScopeStore } from "./stores/sqlite-task-scope-store.ts";
46
+ import type { TaskEventStore } from "./stores/task-event-store.ts";
47
+ import type { TaskScopeStore } from "./stores/task-scope-store.ts";
48
+ import { type TaskStatus, Tasks } from "./task/task-service.ts";
48
49
  import { VERSION } from "./version.ts";
49
50
 
50
51
  /**
@@ -99,7 +100,6 @@ export const EXPECTED_OPERATION_NAMES = [
99
100
  ] as const;
100
101
 
101
102
  export type OperationName = (typeof EXPECTED_OPERATION_NAMES)[number];
102
- type OperationInput = Record<string, unknown>;
103
103
  type OperationHandler = (input: OperationInput) => unknown;
104
104
 
105
105
  export class UnknownOperationError extends Error {}
@@ -107,33 +107,6 @@ export class MigrationRequiredError extends Error {}
107
107
  export class PayloadTooLargeError extends Error {}
108
108
  export { InvalidSessionSecretError };
109
109
 
110
- function string(input: OperationInput, key: string): string {
111
- const value = input[key];
112
- if (typeof value !== "string" || value.length === 0) throw new Error(`${key} is required`);
113
- return value;
114
- }
115
-
116
- function optionalString(input: OperationInput, key: string): string | undefined {
117
- const value = input[key];
118
- if (value === undefined) return undefined;
119
- if (typeof value !== "string") throw new Error(`${key} must be a string`);
120
- return value;
121
- }
122
-
123
- function _optionalStringArray(input: OperationInput, key: string): string[] | undefined {
124
- const value = input[key];
125
- if (value === undefined) return undefined;
126
- if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string")) throw new Error(`${key} must be an array of strings`);
127
- return value as string[];
128
- }
129
-
130
- function optionalNumber(input: OperationInput, key: string): number | undefined {
131
- const value = input[key];
132
- if (value === undefined) return undefined;
133
- if (typeof value !== "number" || !Number.isFinite(value)) throw new Error(`${key} must be a number`);
134
- return value;
135
- }
136
-
137
110
  function normalizeCreateInput(input: OperationInput): CreateArtifactInput {
138
111
  const { template_id, ...rest } = input;
139
112
  return { ...rest, templateId: typeof template_id === "string" ? template_id : undefined } as CreateArtifactInput;
@@ -217,7 +190,7 @@ export interface PapyrusService {
217
190
  execute(operation: string, input?: OperationInput): Promise<unknown>;
218
191
  /**
219
192
  * Every domain migrated onto Vehicle, merged into one registry/one HTTP mount
220
- * (see ./vehicle/papyrus-vehicle.ts) -- one honest VehicleOperation per real
193
+ * (see ./handlers/registry.ts) -- one honest VehicleOperation per real
221
194
  * action, replacing the Pi extension's old `<domain>(action=X)` mega-tools.
222
195
  * Not every domain is migrated yet -- see papyrus-vehicle.ts's own doc comment
223
196
  * for what still isn't and why.
@@ -582,7 +555,7 @@ export function createApp(deps: {
582
555
  /** Defaults to a no-op (createVehicleHttpApp's own default) -- daemon.ts wires vehicleLogger() so a failed invocation is actually logged, not silently discarded. */
583
556
  logger?: Logger;
584
557
  }): { fetch(request: Request): Promise<Response> } {
585
- // Same Bearer token, daemon, and port as the rest of this API -- see ./vehicle/papyrus-vehicle.ts.
558
+ // Same Bearer token, daemon, and port as the rest of this API -- see ./handlers/registry.ts.
586
559
  const vehicleApp = createVehicleHttpApp({ registry: deps.service.vehicle, token: deps.token, logger: deps.logger });
587
560
  return {
588
561
  async fetch(request: Request): Promise<Response> {
@@ -4,8 +4,8 @@ import {
4
4
  releaseSessionIdentity,
5
5
  verifySessionSecret,
6
6
  } from "@danypops/vehicle-server/session-identity";
7
- import { assertValidSessionId } from "./domain/session-identity.ts";
8
- import type { SessionIdentityStore } from "./ports/session-identity-store.ts";
7
+ import { assertValidSessionId } from "../domain/session-identity.ts";
8
+ import type { SessionIdentityStore } from "../stores/session-identity-store.ts";
9
9
 
10
10
  export interface RegisterSessionIdentityResult {
11
11
  sessionId: string;
@@ -2,7 +2,7 @@ import type { SessionIdentityRecord, SessionIdentityStore as VehicleSessionIdent
2
2
 
3
3
  /**
4
4
  * Papyrus's persistence port for @danypops/vehicle-server's storage-agnostic session-identity
5
- * primitive -- re-exported under this project's own port naming convention (src/ports/*)
5
+ * primitive -- re-exported under this project's own port naming convention (src/stores/*)
6
6
  * rather than importing the vehicle-server interface name directly at every call site.
7
7
  */
8
8
  export type SessionIdentityStore = VehicleSessionIdentityStore;
@@ -9,7 +9,7 @@ import {
9
9
  validateDiscussionContent,
10
10
  validateDiscussionOptions,
11
11
  } from "../domain/discussion.ts";
12
- import type { DiscussionRoundStore } from "../ports/discussion-round-store.ts";
12
+ import type { DiscussionRoundStore } from "./discussion-round-store.ts";
13
13
 
14
14
  interface DiscussionRoundRow {
15
15
  id: number;
@@ -1,7 +1,7 @@
1
1
  import type { Db } from "../db.ts";
2
2
  import type { GateResult, GateRunOptions } from "../domain/gate.ts";
3
3
  import { runGates, runGatesAsync } from "../ops.ts";
4
- import type { GateRunner } from "../ports/gate-runner.ts";
4
+ import type { GateRunner } from "./gate-runner.ts";
5
5
 
6
6
  export class SQLiteGateRunner implements GateRunner {
7
7
  constructor(private readonly db: Db) {}
@@ -1,7 +1,7 @@
1
1
  import type { Db } from "../db.ts";
2
2
  import { inTransaction } from "../db.ts";
3
3
  import type { ProjectionCheckpoint } from "../domain/graph-projection.ts";
4
- import type { GraphProjectionStore } from "../ports/graph-projection-store.ts";
4
+ import type { GraphProjectionStore } from "./graph-projection-store.ts";
5
5
 
6
6
  export class SQLiteGraphProjectionStore implements GraphProjectionStore {
7
7
  constructor(private readonly db: Db) {}
@@ -1,6 +1,6 @@
1
1
  import type { Db } from "../db.ts";
2
2
  import type { JsonValue, LogEntry, LogLevel, LogSource } from "../domain/log-entry.ts";
3
- import type { LogStore } from "../ports/log-store.ts";
3
+ import type { LogStore } from "./log-store.ts";
4
4
 
5
5
  interface SourceRow {
6
6
  id: string;