@bradygaster/squad-sdk 0.9.1 → 0.9.2-insider.2
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/README.md +340 -296
- package/dist/agents/history-shadow.d.ts +7 -5
- package/dist/agents/history-shadow.d.ts.map +1 -1
- package/dist/agents/history-shadow.js +69 -78
- package/dist/agents/history-shadow.js.map +1 -1
- package/dist/agents/index.d.ts +12 -1
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +62 -9
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/lifecycle.d.ts +4 -0
- package/dist/agents/lifecycle.d.ts.map +1 -1
- package/dist/agents/lifecycle.js +6 -7
- package/dist/agents/lifecycle.js.map +1 -1
- package/dist/agents/onboarding.d.ts +4 -2
- package/dist/agents/onboarding.d.ts.map +1 -1
- package/dist/agents/onboarding.js +26 -16
- package/dist/agents/onboarding.js.map +1 -1
- package/dist/agents/personal.d.ts +2 -1
- package/dist/agents/personal.d.ts.map +1 -1
- package/dist/agents/personal.js +11 -12
- package/dist/agents/personal.js.map +1 -1
- package/dist/build/bundle.d.ts.map +1 -1
- package/dist/build/bundle.js +6 -6
- package/dist/build/bundle.js.map +1 -1
- package/dist/build/github-dist.js +42 -42
- package/dist/build/release.d.ts.map +1 -1
- package/dist/build/release.js +7 -5
- package/dist/build/release.js.map +1 -1
- package/dist/casting/index.d.ts.map +1 -1
- package/dist/casting/index.js +4 -3
- package/dist/casting/index.js.map +1 -1
- package/dist/config/agent-source.d.ts +5 -1
- package/dist/config/agent-source.d.ts.map +1 -1
- package/dist/config/agent-source.js +85 -41
- package/dist/config/agent-source.js.map +1 -1
- package/dist/config/init.d.ts +4 -3
- package/dist/config/init.d.ts.map +1 -1
- package/dist/config/init.js +257 -236
- package/dist/config/init.js.map +1 -1
- package/dist/config/legacy-fallback.d.ts +3 -2
- package/dist/config/legacy-fallback.d.ts.map +1 -1
- package/dist/config/legacy-fallback.js +16 -14
- package/dist/config/legacy-fallback.js.map +1 -1
- package/dist/config/models.d.ts +9 -6
- package/dist/config/models.d.ts.map +1 -1
- package/dist/config/models.js +35 -25
- package/dist/config/models.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -1
- package/dist/index.js.map +1 -1
- package/dist/marketplace/packaging.d.ts.map +1 -1
- package/dist/marketplace/packaging.js +18 -16
- package/dist/marketplace/packaging.js.map +1 -1
- package/dist/multi-squad.d.ts.map +1 -1
- package/dist/multi-squad.js +10 -9
- package/dist/multi-squad.js.map +1 -1
- package/dist/platform/comms-file-log.d.ts.map +1 -1
- package/dist/platform/comms-file-log.js +7 -6
- package/dist/platform/comms-file-log.js.map +1 -1
- package/dist/platform/comms.d.ts.map +1 -1
- package/dist/platform/comms.js +6 -5
- package/dist/platform/comms.js.map +1 -1
- package/dist/platform/index.d.ts.map +1 -1
- package/dist/platform/index.js +4 -3
- package/dist/platform/index.js.map +1 -1
- package/dist/ralph/capabilities.d.ts +30 -1
- package/dist/ralph/capabilities.d.ts.map +1 -1
- package/dist/ralph/capabilities.js +51 -6
- package/dist/ralph/capabilities.js.map +1 -1
- package/dist/ralph/index.d.ts +1 -1
- package/dist/ralph/index.d.ts.map +1 -1
- package/dist/ralph/index.js +4 -3
- package/dist/ralph/index.js.map +1 -1
- package/dist/ralph/rate-limiting.d.ts.map +1 -1
- package/dist/ralph/rate-limiting.js +4 -4
- package/dist/ralph/rate-limiting.js.map +1 -1
- package/dist/remote/bridge.d.ts.map +1 -1
- package/dist/remote/bridge.js +2 -2
- package/dist/remote/bridge.js.map +1 -1
- package/dist/resolution.d.ts +9 -0
- package/dist/resolution.d.ts.map +1 -1
- package/dist/resolution.js +39 -16
- package/dist/resolution.js.map +1 -1
- package/dist/roles/catalog.d.ts +1 -1
- package/dist/runtime/config.d.ts.map +1 -1
- package/dist/runtime/config.js +8 -7
- package/dist/runtime/config.js.map +1 -1
- package/dist/runtime/cross-squad.d.ts.map +1 -1
- package/dist/runtime/cross-squad.js +8 -7
- package/dist/runtime/cross-squad.js.map +1 -1
- package/dist/runtime/scheduler.d.ts.map +1 -1
- package/dist/runtime/scheduler.js +8 -8
- package/dist/runtime/scheduler.js.map +1 -1
- package/dist/runtime/squad-observer.d.ts.map +1 -1
- package/dist/runtime/squad-observer.js +7 -4
- package/dist/runtime/squad-observer.js.map +1 -1
- package/dist/sharing/consult.d.ts +1 -1
- package/dist/sharing/consult.d.ts.map +1 -1
- package/dist/sharing/consult.js +144 -142
- package/dist/sharing/consult.js.map +1 -1
- package/dist/sharing/export.d.ts.map +1 -1
- package/dist/sharing/export.js +16 -16
- package/dist/sharing/export.js.map +1 -1
- package/dist/sharing/import.d.ts.map +1 -1
- package/dist/sharing/import.js +13 -12
- package/dist/sharing/import.js.map +1 -1
- package/dist/skills/skill-loader.d.ts.map +1 -1
- package/dist/skills/skill-loader.js +10 -9
- package/dist/skills/skill-loader.js.map +1 -1
- package/dist/skills/skill-script-loader.d.ts.map +1 -1
- package/dist/skills/skill-script-loader.js +6 -4
- package/dist/skills/skill-script-loader.js.map +1 -1
- package/dist/skills/skill-source.d.ts +3 -1
- package/dist/skills/skill-source.d.ts.map +1 -1
- package/dist/skills/skill-source.js +18 -16
- package/dist/skills/skill-source.js.map +1 -1
- package/dist/state/collection-map.d.ts +43 -0
- package/dist/state/collection-map.d.ts.map +1 -0
- package/dist/state/collection-map.js +9 -0
- package/dist/state/collection-map.js.map +1 -0
- package/dist/state/collections.d.ts +102 -0
- package/dist/state/collections.d.ts.map +1 -0
- package/dist/state/collections.js +317 -0
- package/dist/state/collections.js.map +1 -0
- package/dist/state/domain-types.d.ts +122 -0
- package/dist/state/domain-types.d.ts.map +1 -0
- package/dist/state/domain-types.js +54 -0
- package/dist/state/domain-types.js.map +1 -0
- package/dist/state/handles.d.ts +16 -0
- package/dist/state/handles.d.ts.map +1 -0
- package/dist/state/handles.js +161 -0
- package/dist/state/handles.js.map +1 -0
- package/dist/state/index.d.ts +17 -0
- package/dist/state/index.d.ts.map +1 -0
- package/dist/state/index.js +15 -0
- package/dist/state/index.js.map +1 -0
- package/dist/state/io/charter-io.d.ts +28 -0
- package/dist/state/io/charter-io.d.ts.map +1 -0
- package/dist/state/io/charter-io.js +94 -0
- package/dist/state/io/charter-io.js.map +1 -0
- package/dist/state/io/decisions-io.d.ts +42 -0
- package/dist/state/io/decisions-io.d.ts.map +1 -0
- package/dist/state/io/decisions-io.js +66 -0
- package/dist/state/io/decisions-io.js.map +1 -0
- package/dist/state/io/history-io.d.ts +37 -0
- package/dist/state/io/history-io.d.ts.map +1 -0
- package/dist/state/io/history-io.js +102 -0
- package/dist/state/io/history-io.js.map +1 -0
- package/dist/state/io/index.d.ts +19 -0
- package/dist/state/io/index.d.ts.map +1 -0
- package/dist/state/io/index.js +19 -0
- package/dist/state/io/index.js.map +1 -0
- package/dist/state/io/routing-io.d.ts +37 -0
- package/dist/state/io/routing-io.d.ts.map +1 -0
- package/dist/state/io/routing-io.js +99 -0
- package/dist/state/io/routing-io.js.map +1 -0
- package/dist/state/io/team-io.d.ts +46 -0
- package/dist/state/io/team-io.d.ts.map +1 -0
- package/dist/state/io/team-io.js +82 -0
- package/dist/state/io/team-io.js.map +1 -0
- package/dist/state/schema.d.ts +24 -0
- package/dist/state/schema.d.ts.map +1 -0
- package/dist/state/schema.js +41 -0
- package/dist/state/schema.js.map +1 -0
- package/dist/state/squad-state.d.ts +42 -0
- package/dist/state/squad-state.d.ts.map +1 -0
- package/dist/state/squad-state.js +68 -0
- package/dist/state/squad-state.js.map +1 -0
- package/dist/storage/fs-storage-provider.d.ts +60 -0
- package/dist/storage/fs-storage-provider.d.ts.map +1 -0
- package/dist/storage/fs-storage-provider.js +377 -0
- package/dist/storage/fs-storage-provider.js.map +1 -0
- package/dist/storage/in-memory-storage-provider.d.ts +46 -0
- package/dist/storage/in-memory-storage-provider.d.ts.map +1 -0
- package/dist/storage/in-memory-storage-provider.js +264 -0
- package/dist/storage/in-memory-storage-provider.js.map +1 -0
- package/dist/storage/index.d.ts +6 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +5 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/sqlite-storage-provider.d.ts +95 -0
- package/dist/storage/sqlite-storage-provider.d.ts.map +1 -0
- package/dist/storage/sqlite-storage-provider.js +383 -0
- package/dist/storage/sqlite-storage-provider.js.map +1 -0
- package/dist/storage/storage-error.d.ts +28 -0
- package/dist/storage/storage-error.d.ts.map +1 -0
- package/dist/storage/storage-error.js +35 -0
- package/dist/storage/storage-error.js.map +1 -0
- package/dist/storage/storage-provider.d.ts +161 -0
- package/dist/storage/storage-provider.d.ts.map +1 -0
- package/dist/storage/storage-provider.js +18 -0
- package/dist/storage/storage-provider.js.map +1 -0
- package/dist/streams/resolver.d.ts.map +1 -1
- package/dist/streams/resolver.js +6 -5
- package/dist/streams/resolver.js.map +1 -1
- package/dist/tools/index.d.ts +5 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +54 -15
- package/dist/tools/index.js.map +1 -1
- package/dist/upstream/resolver.d.ts +3 -2
- package/dist/upstream/resolver.d.ts.map +1 -1
- package/dist/upstream/resolver.js +33 -32
- package/dist/upstream/resolver.js.map +1 -1
- package/package.json +33 -1
- package/templates/casting/Futurama.json +9 -9
- package/templates/casting-history.json +4 -4
- package/templates/casting-policy.json +37 -37
- package/templates/casting-reference.md +104 -104
- package/templates/casting-registry.json +3 -3
- package/templates/ceremonies.md +41 -41
- package/templates/charter.md +53 -53
- package/templates/constraint-tracking.md +38 -38
- package/templates/cooperative-rate-limiting.md +229 -229
- package/templates/copilot-instructions.md +46 -46
- package/templates/history.md +10 -10
- package/templates/identity/now.md +9 -9
- package/templates/identity/wisdom.md +15 -15
- package/templates/issue-lifecycle.md +412 -412
- package/templates/keda-scaler.md +164 -164
- package/templates/machine-capabilities.md +74 -74
- package/templates/mcp-config.md +90 -90
- package/templates/multi-agent-format.md +28 -28
- package/templates/plugin-marketplace.md +49 -49
- package/templates/ralph-circuit-breaker.md +313 -313
- package/templates/raw-agent-output.md +37 -37
- package/templates/roster.md +60 -60
- package/templates/routing.md +39 -39
- package/templates/run-output.md +50 -50
- package/templates/schedule.json +19 -19
- package/templates/scribe-charter.md +123 -119
- package/templates/skill.md +24 -24
- package/templates/skills/agent-collaboration/SKILL.md +42 -42
- package/templates/skills/agent-conduct/SKILL.md +24 -24
- package/templates/skills/architectural-proposals/SKILL.md +151 -151
- package/templates/skills/ci-validation-gates/SKILL.md +84 -84
- package/templates/skills/cli-wiring/SKILL.md +47 -47
- package/templates/skills/client-compatibility/SKILL.md +89 -89
- package/templates/skills/cross-machine-coordination/SKILL.md +434 -0
- package/templates/skills/cross-squad/SKILL.md +114 -114
- package/templates/skills/distributed-mesh/SKILL.md +287 -287
- package/templates/skills/distributed-mesh/mesh.json.example +30 -30
- package/templates/skills/distributed-mesh/sync-mesh.ps1 +111 -111
- package/templates/skills/distributed-mesh/sync-mesh.sh +104 -104
- package/templates/skills/docs-standards/SKILL.md +71 -71
- package/templates/skills/economy-mode/SKILL.md +114 -114
- package/templates/skills/error-recovery/SKILL.md +99 -0
- package/templates/skills/external-comms/SKILL.md +329 -329
- package/templates/skills/gh-auth-isolation/SKILL.md +183 -183
- package/templates/skills/git-workflow/SKILL.md +204 -204
- package/templates/skills/github-multi-account/SKILL.md +95 -95
- package/templates/skills/history-hygiene/SKILL.md +36 -36
- package/templates/skills/humanizer/SKILL.md +105 -105
- package/templates/skills/init-mode/SKILL.md +102 -102
- package/templates/skills/iterative-retrieval/SKILL.md +165 -0
- package/templates/skills/model-selection/SKILL.md +117 -117
- package/templates/skills/nap/SKILL.md +24 -24
- package/templates/skills/notification-routing/SKILL.md +105 -0
- package/templates/skills/personal-squad/SKILL.md +57 -57
- package/templates/skills/pr-screenshots/SKILL.md +149 -0
- package/templates/skills/project-conventions/SKILL.md +56 -56
- package/templates/skills/ralph-two-pass-scan/SKILL.md +35 -0
- package/templates/skills/reflect/SKILL.md +229 -0
- package/templates/skills/release-process/SKILL.md +131 -423
- package/templates/skills/reskill/SKILL.md +92 -92
- package/templates/skills/retro-enforcement/SKILL.md +148 -0
- package/templates/skills/reviewer-protocol/SKILL.md +79 -79
- package/templates/skills/secret-handling/SKILL.md +200 -200
- package/templates/skills/session-recovery/SKILL.md +155 -155
- package/templates/skills/squad-conventions/SKILL.md +69 -69
- package/templates/skills/test-discipline/SKILL.md +37 -37
- package/templates/skills/tiered-memory/SKILL.md +234 -0
- package/templates/skills/windows-compatibility/SKILL.md +98 -74
- package/templates/{squad.agent.md → squad.agent.md.template} +57 -28
- package/templates/workflows/squad-ci.yml +24 -24
- package/templates/workflows/squad-docs.yml +54 -54
- package/templates/workflows/squad-heartbeat.yml +167 -171
- package/templates/workflows/squad-insider-release.yml +61 -61
- package/templates/workflows/squad-issue-assign.yml +161 -161
- package/templates/workflows/squad-label-enforce.yml +181 -181
- package/templates/workflows/squad-preview.yml +55 -55
- package/templates/workflows/squad-promote.yml +120 -120
- package/templates/workflows/squad-release.yml +77 -77
- package/templates/workflows/squad-triage.yml +260 -260
- package/templates/workflows/sync-squad-labels.yml +169 -169
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State Module — SquadState Facade
|
|
3
|
+
*
|
|
4
|
+
* Top-level typed API for reading and writing `.squad/` state.
|
|
5
|
+
* Composes the collection facades (agents, decisions, routing, team)
|
|
6
|
+
* over a pluggable StorageProvider.
|
|
7
|
+
*
|
|
8
|
+
* @module state/squad-state
|
|
9
|
+
*/
|
|
10
|
+
import type { StorageProvider } from '../storage/storage-provider.js';
|
|
11
|
+
import { AgentsCollection, ConfigCollection, DecisionsCollection, LogCollection, RoutingCollection, SkillsCollection, TeamCollection, TemplatesCollection } from './collections.js';
|
|
12
|
+
export declare class SquadState {
|
|
13
|
+
private readonly storage;
|
|
14
|
+
private readonly _rootDir;
|
|
15
|
+
readonly agents: AgentsCollection;
|
|
16
|
+
readonly config: ConfigCollection;
|
|
17
|
+
readonly decisions: DecisionsCollection;
|
|
18
|
+
readonly routing: RoutingCollection;
|
|
19
|
+
readonly team: TeamCollection;
|
|
20
|
+
readonly skills: SkillsCollection;
|
|
21
|
+
readonly templates: TemplatesCollection;
|
|
22
|
+
readonly log: LogCollection;
|
|
23
|
+
private constructor();
|
|
24
|
+
/** The project root directory this SquadState is bound to. */
|
|
25
|
+
get root(): string;
|
|
26
|
+
/** The underlying StorageProvider used by this instance. */
|
|
27
|
+
get provider(): StorageProvider;
|
|
28
|
+
/**
|
|
29
|
+
* Factory method — validates that `rootDir/.squad/` exists before
|
|
30
|
+
* returning a new SquadState instance.
|
|
31
|
+
*/
|
|
32
|
+
static create(storage: StorageProvider, rootDir: string): Promise<SquadState>;
|
|
33
|
+
/**
|
|
34
|
+
* Synchronous factory — creates SquadState without validating `.squad/`
|
|
35
|
+
* existence. For internal SDK use where the caller already knows the
|
|
36
|
+
* root is initialized (e.g., modules operating on an existing project).
|
|
37
|
+
*/
|
|
38
|
+
static fromStorage(storage: StorageProvider, rootDir: string): SquadState;
|
|
39
|
+
/** Check if a `.squad/` directory exists at the root. */
|
|
40
|
+
isInitialized(): Promise<boolean>;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=squad-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"squad-state.d.ts","sourceRoot":"","sources":["../../src/state/squad-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,mBAAmB,EACpB,MAAM,kBAAkB,CAAC;AAG1B,qBAAa,UAAU;IAWnB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAX3B,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,mBAAmB,CAAC;IACxC,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC;IACpC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,mBAAmB,CAAC;IACxC,QAAQ,CAAC,GAAG,EAAE,aAAa,CAAC;IAE5B,OAAO;IAcP,8DAA8D;IAC9D,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,4DAA4D;IAC5D,IAAI,QAAQ,IAAI,eAAe,CAE9B;IAED;;;OAGG;WACU,MAAM,CACjB,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,UAAU,CAAC;IAStB;;;;OAIG;IACH,MAAM,CAAC,WAAW,CAChB,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,MAAM,GACd,UAAU;IAIb,yDAAyD;IACnD,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC;CAGxC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State Module — SquadState Facade
|
|
3
|
+
*
|
|
4
|
+
* Top-level typed API for reading and writing `.squad/` state.
|
|
5
|
+
* Composes the collection facades (agents, decisions, routing, team)
|
|
6
|
+
* over a pluggable StorageProvider.
|
|
7
|
+
*
|
|
8
|
+
* @module state/squad-state
|
|
9
|
+
*/
|
|
10
|
+
import { AgentsCollection, ConfigCollection, DecisionsCollection, LogCollection, RoutingCollection, SkillsCollection, TeamCollection, TemplatesCollection, } from './collections.js';
|
|
11
|
+
import { NotFoundError } from './domain-types.js';
|
|
12
|
+
export class SquadState {
|
|
13
|
+
storage;
|
|
14
|
+
_rootDir;
|
|
15
|
+
agents;
|
|
16
|
+
config;
|
|
17
|
+
decisions;
|
|
18
|
+
routing;
|
|
19
|
+
team;
|
|
20
|
+
skills;
|
|
21
|
+
templates;
|
|
22
|
+
log;
|
|
23
|
+
constructor(storage, _rootDir) {
|
|
24
|
+
this.storage = storage;
|
|
25
|
+
this._rootDir = _rootDir;
|
|
26
|
+
this.agents = new AgentsCollection(storage, _rootDir);
|
|
27
|
+
this.config = new ConfigCollection(storage, _rootDir);
|
|
28
|
+
this.decisions = new DecisionsCollection(storage, _rootDir);
|
|
29
|
+
this.routing = new RoutingCollection(storage, _rootDir);
|
|
30
|
+
this.team = new TeamCollection(storage, _rootDir);
|
|
31
|
+
this.skills = new SkillsCollection(storage, _rootDir);
|
|
32
|
+
this.templates = new TemplatesCollection(storage, _rootDir);
|
|
33
|
+
this.log = new LogCollection(storage, _rootDir);
|
|
34
|
+
}
|
|
35
|
+
/** The project root directory this SquadState is bound to. */
|
|
36
|
+
get root() {
|
|
37
|
+
return this._rootDir;
|
|
38
|
+
}
|
|
39
|
+
/** The underlying StorageProvider used by this instance. */
|
|
40
|
+
get provider() {
|
|
41
|
+
return this.storage;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Factory method — validates that `rootDir/.squad/` exists before
|
|
45
|
+
* returning a new SquadState instance.
|
|
46
|
+
*/
|
|
47
|
+
static async create(storage, rootDir) {
|
|
48
|
+
const squadDir = `${rootDir}/.squad`;
|
|
49
|
+
const exists = await storage.exists(squadDir);
|
|
50
|
+
if (!exists) {
|
|
51
|
+
throw new NotFoundError('squad', rootDir);
|
|
52
|
+
}
|
|
53
|
+
return new SquadState(storage, rootDir);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Synchronous factory — creates SquadState without validating `.squad/`
|
|
57
|
+
* existence. For internal SDK use where the caller already knows the
|
|
58
|
+
* root is initialized (e.g., modules operating on an existing project).
|
|
59
|
+
*/
|
|
60
|
+
static fromStorage(storage, rootDir) {
|
|
61
|
+
return new SquadState(storage, rootDir);
|
|
62
|
+
}
|
|
63
|
+
/** Check if a `.squad/` directory exists at the root. */
|
|
64
|
+
async isInitialized() {
|
|
65
|
+
return this.storage.exists(`${this._rootDir}/.squad`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=squad-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"squad-state.js","sourceRoot":"","sources":["../../src/state/squad-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,MAAM,OAAO,UAAU;IAWF;IACA;IAXV,MAAM,CAAmB;IACzB,MAAM,CAAmB;IACzB,SAAS,CAAsB;IAC/B,OAAO,CAAoB;IAC3B,IAAI,CAAiB;IACrB,MAAM,CAAmB;IACzB,SAAS,CAAsB;IAC/B,GAAG,CAAgB;IAE5B,YACmB,OAAwB,EACxB,QAAgB;QADhB,YAAO,GAAP,OAAO,CAAiB;QACxB,aAAQ,GAAR,QAAQ,CAAQ;QAEjC,IAAI,CAAC,MAAM,GAAG,IAAI,gBAAgB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACtD,IAAI,CAAC,MAAM,GAAG,IAAI,gBAAgB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACtD,IAAI,CAAC,SAAS,GAAG,IAAI,mBAAmB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC5D,IAAI,CAAC,OAAO,GAAG,IAAI,iBAAiB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACxD,IAAI,CAAC,IAAI,GAAG,IAAI,cAAc,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM,GAAG,IAAI,gBAAgB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACtD,IAAI,CAAC,SAAS,GAAG,IAAI,mBAAmB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC5D,IAAI,CAAC,GAAG,GAAG,IAAI,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAClD,CAAC;IAED,8DAA8D;IAC9D,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,4DAA4D;IAC5D,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,KAAK,CAAC,MAAM,CACjB,OAAwB,EACxB,OAAe;QAEf,MAAM,QAAQ,GAAG,GAAG,OAAO,SAAS,CAAC;QACrC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC9C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,IAAI,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,WAAW,CAChB,OAAwB,EACxB,OAAe;QAEf,OAAO,IAAI,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC;IAED,yDAAyD;IACzD,KAAK,CAAC,aAAa;QACjB,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,SAAS,CAAC,CAAC;IACxD,CAAC;CACF"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { StorageProvider, StorageStats } from './storage-provider.js';
|
|
2
|
+
/**
|
|
3
|
+
* FSStorageProvider — Node.js `fs` implementation of StorageProvider.
|
|
4
|
+
*
|
|
5
|
+
* - ENOENT reads return `undefined` (no throw).
|
|
6
|
+
* - Writes create parent directories recursively.
|
|
7
|
+
* - Appends create the file (and parent dirs) if missing.
|
|
8
|
+
* - delete is a no-op when the file does not exist.
|
|
9
|
+
* - list returns an empty array for a missing directory.
|
|
10
|
+
* - Optional `rootDir` confines all operations to a specific directory tree.
|
|
11
|
+
*/
|
|
12
|
+
export declare class FSStorageProvider implements StorageProvider {
|
|
13
|
+
private static readonly CASE_INSENSITIVE;
|
|
14
|
+
private readonly rootDir?;
|
|
15
|
+
constructor(rootDir?: string);
|
|
16
|
+
private pathStartsWith;
|
|
17
|
+
private pathEquals;
|
|
18
|
+
/**
|
|
19
|
+
* Validates that filePath resolves within rootDir and does not escape
|
|
20
|
+
* via path traversal or symlinks.
|
|
21
|
+
*
|
|
22
|
+
* ⚠️ TOCTOU: This is a user-space check. Between validation and the
|
|
23
|
+
* subsequent fs operation, a path component could theoretically be
|
|
24
|
+
* swapped for a symlink. This is an inherent limitation of user-space
|
|
25
|
+
* path validation on POSIX systems. For defense-in-depth, callers
|
|
26
|
+
* operating in hostile environments should use OS-level confinement
|
|
27
|
+
* (chroot, namespaces, or sandboxing) in addition to this check.
|
|
28
|
+
*/
|
|
29
|
+
private assertSafePath;
|
|
30
|
+
private assertSafePathSync;
|
|
31
|
+
read(filePath: string): Promise<string | undefined>;
|
|
32
|
+
write(filePath: string, data: string): Promise<void>;
|
|
33
|
+
append(filePath: string, data: string): Promise<void>;
|
|
34
|
+
exists(filePath: string): Promise<boolean>;
|
|
35
|
+
list(dirPath: string): Promise<string[]>;
|
|
36
|
+
delete(filePath: string): Promise<void>;
|
|
37
|
+
readSync(filePath: string): string | undefined;
|
|
38
|
+
writeSync(filePath: string, data: string): void;
|
|
39
|
+
existsSync(filePath: string): boolean;
|
|
40
|
+
listSync(dirPath: string): string[];
|
|
41
|
+
deleteDir(dirPath: string): Promise<void>;
|
|
42
|
+
isDirectory(targetPath: string): Promise<boolean>;
|
|
43
|
+
mkdir(dirPath: string, options?: {
|
|
44
|
+
recursive?: boolean;
|
|
45
|
+
}): Promise<void>;
|
|
46
|
+
rename(oldPath: string, newPath: string): Promise<void>;
|
|
47
|
+
copy(srcPath: string, destPath: string): Promise<void>;
|
|
48
|
+
stat(targetPath: string): Promise<StorageStats | undefined>;
|
|
49
|
+
isDirectorySync(targetPath: string): boolean;
|
|
50
|
+
mkdirSync(dirPath: string, options?: {
|
|
51
|
+
recursive?: boolean;
|
|
52
|
+
}): void;
|
|
53
|
+
statSync(targetPath: string): StorageStats | undefined;
|
|
54
|
+
appendSync(filePath: string, data: string): void;
|
|
55
|
+
deleteSync(filePath: string): void;
|
|
56
|
+
renameSync(oldPath: string, newPath: string): void;
|
|
57
|
+
copySync(srcPath: string, destPath: string): void;
|
|
58
|
+
deleteDirSync(dirPath: string): void;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=fs-storage-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs-storage-provider.d.ts","sourceRoot":"","sources":["../../src/storage/fs-storage-provider.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAG3E;;;;;;;;;GASG;AACH,qBAAa,iBAAkB,YAAW,eAAe;IACvD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAiE;IACzG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAS;gBAEtB,OAAO,CAAC,EAAE,MAAM;IAI5B,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,UAAU;IAOlB;;;;;;;;;;OAUG;YACW,cAAc;IAwC5B,OAAO,CAAC,kBAAkB;IAwCpB,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAUnD,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUpD,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUrD,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAU1C,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAUxC,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAU7C,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAU9C,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAU/C,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAKrC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE;IAU7B,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYzC,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUjD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAUxE,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWvD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWtD,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;IAWjE,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAS5C,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI;IAUnE,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAWtD,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAUhD,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAUlC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAWlD,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAWjD,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;CASrC"}
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
import { readFile, writeFile, appendFile, access, readdir, unlink, mkdir as fsMkdir, realpath, rm, stat as fsStat, rename as fsRename, copyFile } from 'fs/promises';
|
|
2
|
+
import { readFileSync, writeFileSync, appendFileSync, existsSync as fsExistsSync, mkdirSync as fsMkdirSync, realpathSync, readdirSync, statSync, unlinkSync, renameSync as fsRenameSync, copyFileSync, rmSync } from 'fs';
|
|
3
|
+
import { dirname, resolve, sep } from 'path';
|
|
4
|
+
import { StorageError } from './storage-error.js';
|
|
5
|
+
/**
|
|
6
|
+
* FSStorageProvider — Node.js `fs` implementation of StorageProvider.
|
|
7
|
+
*
|
|
8
|
+
* - ENOENT reads return `undefined` (no throw).
|
|
9
|
+
* - Writes create parent directories recursively.
|
|
10
|
+
* - Appends create the file (and parent dirs) if missing.
|
|
11
|
+
* - delete is a no-op when the file does not exist.
|
|
12
|
+
* - list returns an empty array for a missing directory.
|
|
13
|
+
* - Optional `rootDir` confines all operations to a specific directory tree.
|
|
14
|
+
*/
|
|
15
|
+
export class FSStorageProvider {
|
|
16
|
+
static CASE_INSENSITIVE = process.platform === 'win32' || process.platform === 'darwin';
|
|
17
|
+
rootDir;
|
|
18
|
+
constructor(rootDir) {
|
|
19
|
+
this.rootDir = rootDir ? realpathSync(resolve(rootDir)) : undefined;
|
|
20
|
+
}
|
|
21
|
+
pathStartsWith(fullPath, prefix) {
|
|
22
|
+
if (FSStorageProvider.CASE_INSENSITIVE) {
|
|
23
|
+
return fullPath.toLowerCase().startsWith(prefix.toLowerCase());
|
|
24
|
+
}
|
|
25
|
+
return fullPath.startsWith(prefix);
|
|
26
|
+
}
|
|
27
|
+
pathEquals(a, b) {
|
|
28
|
+
if (FSStorageProvider.CASE_INSENSITIVE) {
|
|
29
|
+
return a.toLowerCase() === b.toLowerCase();
|
|
30
|
+
}
|
|
31
|
+
return a === b;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Validates that filePath resolves within rootDir and does not escape
|
|
35
|
+
* via path traversal or symlinks.
|
|
36
|
+
*
|
|
37
|
+
* ⚠️ TOCTOU: This is a user-space check. Between validation and the
|
|
38
|
+
* subsequent fs operation, a path component could theoretically be
|
|
39
|
+
* swapped for a symlink. This is an inherent limitation of user-space
|
|
40
|
+
* path validation on POSIX systems. For defense-in-depth, callers
|
|
41
|
+
* operating in hostile environments should use OS-level confinement
|
|
42
|
+
* (chroot, namespaces, or sandboxing) in addition to this check.
|
|
43
|
+
*/
|
|
44
|
+
async assertSafePath(filePath) {
|
|
45
|
+
if (!this.rootDir)
|
|
46
|
+
return filePath;
|
|
47
|
+
const resolved = resolve(this.rootDir, filePath);
|
|
48
|
+
// Check if resolved path is within rootDir
|
|
49
|
+
if (!this.pathStartsWith(resolved, this.rootDir + sep) && !this.pathEquals(resolved, this.rootDir)) {
|
|
50
|
+
throw new Error(`Path traversal blocked: ${filePath}`);
|
|
51
|
+
}
|
|
52
|
+
// Check for symlink traversal
|
|
53
|
+
try {
|
|
54
|
+
const real = await realpath(resolved);
|
|
55
|
+
if (!this.pathStartsWith(real, this.rootDir + sep) && !this.pathEquals(real, this.rootDir)) {
|
|
56
|
+
throw new Error(`Symlink traversal blocked: ${filePath}`);
|
|
57
|
+
}
|
|
58
|
+
return real;
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
if (err.code === 'ENOENT') {
|
|
62
|
+
// Walk up to nearest existing ancestor and verify it resolves within rootDir
|
|
63
|
+
let checkPath = resolved;
|
|
64
|
+
while (!this.pathEquals(checkPath, this.rootDir)) {
|
|
65
|
+
checkPath = dirname(checkPath);
|
|
66
|
+
try {
|
|
67
|
+
const realAncestor = await realpath(checkPath);
|
|
68
|
+
if (!this.pathStartsWith(realAncestor, this.rootDir + sep) && !this.pathEquals(realAncestor, this.rootDir)) {
|
|
69
|
+
throw new Error(`Symlink traversal blocked: ${filePath}`);
|
|
70
|
+
}
|
|
71
|
+
return resolved;
|
|
72
|
+
}
|
|
73
|
+
catch (ancestorErr) {
|
|
74
|
+
if (ancestorErr.code === 'ENOENT')
|
|
75
|
+
continue;
|
|
76
|
+
throw ancestorErr;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return resolved;
|
|
80
|
+
}
|
|
81
|
+
throw err;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
assertSafePathSync(filePath) {
|
|
85
|
+
if (!this.rootDir)
|
|
86
|
+
return filePath;
|
|
87
|
+
const resolved = resolve(this.rootDir, filePath);
|
|
88
|
+
// Check if resolved path is within rootDir
|
|
89
|
+
if (!this.pathStartsWith(resolved, this.rootDir + sep) && !this.pathEquals(resolved, this.rootDir)) {
|
|
90
|
+
throw new Error(`Path traversal blocked: ${filePath}`);
|
|
91
|
+
}
|
|
92
|
+
// Check for symlink traversal
|
|
93
|
+
try {
|
|
94
|
+
const real = realpathSync(resolved);
|
|
95
|
+
if (!this.pathStartsWith(real, this.rootDir + sep) && !this.pathEquals(real, this.rootDir)) {
|
|
96
|
+
throw new Error(`Symlink traversal blocked: ${filePath}`);
|
|
97
|
+
}
|
|
98
|
+
return real;
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
if (err.code === 'ENOENT') {
|
|
102
|
+
// Walk up to nearest existing ancestor and verify it resolves within rootDir
|
|
103
|
+
let checkPath = resolved;
|
|
104
|
+
while (!this.pathEquals(checkPath, this.rootDir)) {
|
|
105
|
+
checkPath = dirname(checkPath);
|
|
106
|
+
try {
|
|
107
|
+
const realAncestor = realpathSync(checkPath);
|
|
108
|
+
if (!this.pathStartsWith(realAncestor, this.rootDir + sep) && !this.pathEquals(realAncestor, this.rootDir)) {
|
|
109
|
+
throw new Error(`Symlink traversal blocked: ${filePath}`);
|
|
110
|
+
}
|
|
111
|
+
return resolved;
|
|
112
|
+
}
|
|
113
|
+
catch (ancestorErr) {
|
|
114
|
+
if (ancestorErr.code === 'ENOENT')
|
|
115
|
+
continue;
|
|
116
|
+
throw ancestorErr;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return resolved;
|
|
120
|
+
}
|
|
121
|
+
throw err;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
async read(filePath) {
|
|
125
|
+
const safePath = await this.assertSafePath(filePath);
|
|
126
|
+
try {
|
|
127
|
+
return await readFile(safePath, 'utf-8');
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
if (err.code === 'ENOENT')
|
|
131
|
+
return undefined;
|
|
132
|
+
throw new StorageError('read', filePath, err);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
async write(filePath, data) {
|
|
136
|
+
const safePath = await this.assertSafePath(filePath);
|
|
137
|
+
try {
|
|
138
|
+
await fsMkdir(dirname(safePath), { recursive: true });
|
|
139
|
+
await writeFile(safePath, data, 'utf-8');
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
throw new StorageError('write', filePath, err);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
async append(filePath, data) {
|
|
146
|
+
const safePath = await this.assertSafePath(filePath);
|
|
147
|
+
try {
|
|
148
|
+
await fsMkdir(dirname(safePath), { recursive: true });
|
|
149
|
+
await appendFile(safePath, data, 'utf-8');
|
|
150
|
+
}
|
|
151
|
+
catch (err) {
|
|
152
|
+
throw new StorageError('append', filePath, err);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
async exists(filePath) {
|
|
156
|
+
const safePath = await this.assertSafePath(filePath);
|
|
157
|
+
try {
|
|
158
|
+
await access(safePath);
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
async list(dirPath) {
|
|
166
|
+
const safePath = await this.assertSafePath(dirPath);
|
|
167
|
+
try {
|
|
168
|
+
return await readdir(safePath);
|
|
169
|
+
}
|
|
170
|
+
catch (err) {
|
|
171
|
+
if (err.code === 'ENOENT')
|
|
172
|
+
return [];
|
|
173
|
+
throw new StorageError('list', dirPath, err);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
async delete(filePath) {
|
|
177
|
+
const safePath = await this.assertSafePath(filePath);
|
|
178
|
+
try {
|
|
179
|
+
await unlink(safePath);
|
|
180
|
+
}
|
|
181
|
+
catch (err) {
|
|
182
|
+
if (err.code === 'ENOENT')
|
|
183
|
+
return;
|
|
184
|
+
throw new StorageError('delete', filePath, err);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
readSync(filePath) {
|
|
188
|
+
const safePath = this.assertSafePathSync(filePath);
|
|
189
|
+
try {
|
|
190
|
+
return readFileSync(safePath, 'utf-8');
|
|
191
|
+
}
|
|
192
|
+
catch (err) {
|
|
193
|
+
if (err.code === 'ENOENT')
|
|
194
|
+
return undefined;
|
|
195
|
+
throw new StorageError('read', filePath, err);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
writeSync(filePath, data) {
|
|
199
|
+
const safePath = this.assertSafePathSync(filePath);
|
|
200
|
+
try {
|
|
201
|
+
fsMkdirSync(dirname(safePath), { recursive: true });
|
|
202
|
+
writeFileSync(safePath, data, 'utf-8');
|
|
203
|
+
}
|
|
204
|
+
catch (err) {
|
|
205
|
+
throw new StorageError('write', filePath, err);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
existsSync(filePath) {
|
|
209
|
+
const safePath = this.assertSafePathSync(filePath);
|
|
210
|
+
return fsExistsSync(safePath);
|
|
211
|
+
}
|
|
212
|
+
listSync(dirPath) {
|
|
213
|
+
const safePath = this.assertSafePathSync(dirPath);
|
|
214
|
+
try {
|
|
215
|
+
return readdirSync(safePath);
|
|
216
|
+
}
|
|
217
|
+
catch (err) {
|
|
218
|
+
if (err.code === 'ENOENT')
|
|
219
|
+
return [];
|
|
220
|
+
throw new StorageError('list', dirPath, err);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
async deleteDir(dirPath) {
|
|
224
|
+
const safePath = await this.assertSafePath(dirPath);
|
|
225
|
+
try {
|
|
226
|
+
await rm(safePath, { recursive: true, force: true });
|
|
227
|
+
}
|
|
228
|
+
catch (err) {
|
|
229
|
+
if (err.code === 'ENOENT')
|
|
230
|
+
return;
|
|
231
|
+
throw new StorageError('deleteDir', dirPath, err);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
// ── Phase 3 Wave 1 additions ────────────────────────────────────────────
|
|
235
|
+
async isDirectory(targetPath) {
|
|
236
|
+
const safePath = await this.assertSafePath(targetPath);
|
|
237
|
+
try {
|
|
238
|
+
const s = await fsStat(safePath);
|
|
239
|
+
return s.isDirectory();
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
async mkdir(dirPath, options) {
|
|
246
|
+
const safePath = await this.assertSafePath(dirPath);
|
|
247
|
+
try {
|
|
248
|
+
await fsMkdir(safePath, { recursive: options?.recursive ?? false });
|
|
249
|
+
}
|
|
250
|
+
catch (err) {
|
|
251
|
+
if (err.code === 'EEXIST')
|
|
252
|
+
return;
|
|
253
|
+
throw new StorageError('mkdir', dirPath, err);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
async rename(oldPath, newPath) {
|
|
257
|
+
const safeOld = await this.assertSafePath(oldPath);
|
|
258
|
+
const safeNew = await this.assertSafePath(newPath);
|
|
259
|
+
try {
|
|
260
|
+
await fsMkdir(dirname(safeNew), { recursive: true });
|
|
261
|
+
await fsRename(safeOld, safeNew);
|
|
262
|
+
}
|
|
263
|
+
catch (err) {
|
|
264
|
+
throw new StorageError('rename', oldPath, err);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
async copy(srcPath, destPath) {
|
|
268
|
+
const safeSrc = await this.assertSafePath(srcPath);
|
|
269
|
+
const safeDest = await this.assertSafePath(destPath);
|
|
270
|
+
try {
|
|
271
|
+
await fsMkdir(dirname(safeDest), { recursive: true });
|
|
272
|
+
await copyFile(safeSrc, safeDest);
|
|
273
|
+
}
|
|
274
|
+
catch (err) {
|
|
275
|
+
throw new StorageError('copy', srcPath, err);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
async stat(targetPath) {
|
|
279
|
+
const safePath = await this.assertSafePath(targetPath);
|
|
280
|
+
try {
|
|
281
|
+
const s = await fsStat(safePath);
|
|
282
|
+
return { size: s.size, mtimeMs: s.mtimeMs, isDirectory: s.isDirectory() };
|
|
283
|
+
}
|
|
284
|
+
catch (err) {
|
|
285
|
+
if (err.code === 'ENOENT')
|
|
286
|
+
return undefined;
|
|
287
|
+
throw new StorageError('stat', targetPath, err);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
isDirectorySync(targetPath) {
|
|
291
|
+
const safePath = this.assertSafePathSync(targetPath);
|
|
292
|
+
try {
|
|
293
|
+
return statSync(safePath).isDirectory();
|
|
294
|
+
}
|
|
295
|
+
catch {
|
|
296
|
+
return false;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
mkdirSync(dirPath, options) {
|
|
300
|
+
const safePath = this.assertSafePathSync(dirPath);
|
|
301
|
+
try {
|
|
302
|
+
fsMkdirSync(safePath, { recursive: options?.recursive ?? false });
|
|
303
|
+
}
|
|
304
|
+
catch (err) {
|
|
305
|
+
if (err.code === 'EEXIST')
|
|
306
|
+
return;
|
|
307
|
+
throw new StorageError('mkdir', dirPath, err);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
statSync(targetPath) {
|
|
311
|
+
const safePath = this.assertSafePathSync(targetPath);
|
|
312
|
+
try {
|
|
313
|
+
const s = statSync(safePath);
|
|
314
|
+
return { size: s.size, mtimeMs: s.mtimeMs, isDirectory: s.isDirectory() };
|
|
315
|
+
}
|
|
316
|
+
catch (err) {
|
|
317
|
+
if (err.code === 'ENOENT')
|
|
318
|
+
return undefined;
|
|
319
|
+
throw new StorageError('stat', targetPath, err);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
appendSync(filePath, data) {
|
|
323
|
+
const safePath = this.assertSafePathSync(filePath);
|
|
324
|
+
try {
|
|
325
|
+
fsMkdirSync(dirname(safePath), { recursive: true });
|
|
326
|
+
appendFileSync(safePath, data, 'utf-8');
|
|
327
|
+
}
|
|
328
|
+
catch (err) {
|
|
329
|
+
throw new StorageError('append', filePath, err);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
deleteSync(filePath) {
|
|
333
|
+
const safePath = this.assertSafePathSync(filePath);
|
|
334
|
+
try {
|
|
335
|
+
unlinkSync(safePath);
|
|
336
|
+
}
|
|
337
|
+
catch (err) {
|
|
338
|
+
if (err.code === 'ENOENT')
|
|
339
|
+
return;
|
|
340
|
+
throw new StorageError('delete', filePath, err);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
renameSync(oldPath, newPath) {
|
|
344
|
+
const safeOld = this.assertSafePathSync(oldPath);
|
|
345
|
+
const safeNew = this.assertSafePathSync(newPath);
|
|
346
|
+
try {
|
|
347
|
+
fsMkdirSync(dirname(safeNew), { recursive: true });
|
|
348
|
+
fsRenameSync(safeOld, safeNew);
|
|
349
|
+
}
|
|
350
|
+
catch (err) {
|
|
351
|
+
throw new StorageError('rename', oldPath, err);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
copySync(srcPath, destPath) {
|
|
355
|
+
const safeSrc = this.assertSafePathSync(srcPath);
|
|
356
|
+
const safeDest = this.assertSafePathSync(destPath);
|
|
357
|
+
try {
|
|
358
|
+
fsMkdirSync(dirname(safeDest), { recursive: true });
|
|
359
|
+
copyFileSync(safeSrc, safeDest);
|
|
360
|
+
}
|
|
361
|
+
catch (err) {
|
|
362
|
+
throw new StorageError('copy', srcPath, err);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
deleteDirSync(dirPath) {
|
|
366
|
+
const safePath = this.assertSafePathSync(dirPath);
|
|
367
|
+
try {
|
|
368
|
+
rmSync(safePath, { recursive: true, force: true });
|
|
369
|
+
}
|
|
370
|
+
catch (err) {
|
|
371
|
+
if (err.code === 'ENOENT')
|
|
372
|
+
return;
|
|
373
|
+
throw new StorageError('deleteDir', dirPath, err);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
//# sourceMappingURL=fs-storage-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs-storage-provider.js","sourceRoot":"","sources":["../../src/storage/fs-storage-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { StorageProvider, StorageStats } from './storage-provider.js';
|
|
2
|
+
/**
|
|
3
|
+
* InMemoryStorageProvider — test-friendly StorageProvider backed by a Map.
|
|
4
|
+
*
|
|
5
|
+
* No filesystem access. All paths are normalized to forward-slash POSIX form.
|
|
6
|
+
* Useful for unit tests and DI scenarios where real I/O is undesirable.
|
|
7
|
+
*/
|
|
8
|
+
export declare class InMemoryStorageProvider implements StorageProvider {
|
|
9
|
+
private files;
|
|
10
|
+
/** Track write timestamps for stat(). Key = normalized path, value = epoch ms. */
|
|
11
|
+
private mtimes;
|
|
12
|
+
private norm;
|
|
13
|
+
read(filePath: string): Promise<string | undefined>;
|
|
14
|
+
write(filePath: string, data: string): Promise<void>;
|
|
15
|
+
append(filePath: string, data: string): Promise<void>;
|
|
16
|
+
exists(filePath: string): Promise<boolean>;
|
|
17
|
+
list(dirPath: string): Promise<string[]>;
|
|
18
|
+
delete(filePath: string): Promise<void>;
|
|
19
|
+
deleteDir(dirPath: string): Promise<void>;
|
|
20
|
+
isDirectory(targetPath: string): Promise<boolean>;
|
|
21
|
+
mkdir(dirPath: string, _options?: {
|
|
22
|
+
recursive?: boolean;
|
|
23
|
+
}): Promise<void>;
|
|
24
|
+
rename(oldPath: string, newPath: string): Promise<void>;
|
|
25
|
+
copy(srcPath: string, destPath: string): Promise<void>;
|
|
26
|
+
stat(targetPath: string): Promise<StorageStats | undefined>;
|
|
27
|
+
readSync(filePath: string): string | undefined;
|
|
28
|
+
writeSync(filePath: string, data: string): void;
|
|
29
|
+
existsSync(filePath: string): boolean;
|
|
30
|
+
listSync(dirPath: string): string[];
|
|
31
|
+
isDirectorySync(targetPath: string): boolean;
|
|
32
|
+
mkdirSync(_dirPath: string, _options?: {
|
|
33
|
+
recursive?: boolean;
|
|
34
|
+
}): void;
|
|
35
|
+
statSync(targetPath: string): StorageStats | undefined;
|
|
36
|
+
appendSync(filePath: string, data: string): void;
|
|
37
|
+
deleteSync(filePath: string): void;
|
|
38
|
+
renameSync(oldPath: string, newPath: string): void;
|
|
39
|
+
copySync(srcPath: string, destPath: string): void;
|
|
40
|
+
deleteDirSync(dirPath: string): void;
|
|
41
|
+
/** Return a shallow copy of the internal state for test assertions. */
|
|
42
|
+
snapshot(): Map<string, string>;
|
|
43
|
+
/** Reset all stored files. */
|
|
44
|
+
clear(): void;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=in-memory-storage-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-memory-storage-provider.d.ts","sourceRoot":"","sources":["../../src/storage/in-memory-storage-provider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE3E;;;;;GAKG;AACH,qBAAa,uBAAwB,YAAW,eAAe;IAC7D,OAAO,CAAC,KAAK,CAA6B;IAC1C,kFAAkF;IAClF,OAAO,CAAC,MAAM,CAA6B;IAE3C,OAAO,CAAC,IAAI;IAMN,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAInD,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpD,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrD,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI1C,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAIxC,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMvC,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYzC,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIjD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzE,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqCvD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAatD,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;IA0BjE,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI9C,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAM/C,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAWrC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE;IAcnC,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAW5C,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI;IAKrE,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAwBtD,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAOhD,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAMlC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAqClD,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAajD,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAYpC,uEAAuE;IACvE,QAAQ,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IAI/B,8BAA8B;IAC9B,KAAK,IAAI,IAAI;CAId"}
|