@intentic/sandbox-contract 1.239.0 → 1.242.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -16
- package/dist/agent-catalog.d.ts +5 -28
- package/dist/agent-catalog.d.ts.map +1 -1
- package/dist/agent-catalog.js +21 -157
- package/dist/agent-catalog.js.map +1 -1
- package/dist/agent-run-model.d.ts +3 -2
- package/dist/agent-run-model.d.ts.map +1 -1
- package/dist/agent-run-model.js +9 -6
- package/dist/agent-run-model.js.map +1 -1
- package/dist/agent-runtimes.d.ts +27 -0
- package/dist/agent-runtimes.d.ts.map +1 -0
- package/dist/agent-runtimes.js +113 -0
- package/dist/agent-runtimes.js.map +1 -0
- package/dist/approvals-execution.d.ts +11 -0
- package/dist/approvals-execution.d.ts.map +1 -0
- package/dist/approvals-execution.js +44 -0
- package/dist/approvals-execution.js.map +1 -0
- package/dist/arrival.d.ts +151 -0
- package/dist/arrival.d.ts.map +1 -0
- package/dist/arrival.js +56 -0
- package/dist/arrival.js.map +1 -0
- package/dist/card-status.d.ts +5 -0
- package/dist/card-status.d.ts.map +1 -0
- package/dist/card-status.js +74 -0
- package/dist/card-status.js.map +1 -0
- package/dist/chores/chores.d.ts.map +1 -1
- package/dist/chores/chores.js +1 -1
- package/dist/chores/chores.js.map +1 -1
- package/dist/command-classes.d.ts +0 -1
- package/dist/command-classes.d.ts.map +1 -1
- package/dist/command-classes.js +9 -2
- package/dist/command-classes.js.map +1 -1
- package/dist/command-run.d.ts +10 -0
- package/dist/command-run.d.ts.map +1 -0
- package/dist/command-run.js +46 -0
- package/dist/command-run.js.map +1 -0
- package/dist/contracts/agent.contract.d.ts +991 -771
- package/dist/contracts/agent.contract.d.ts.map +1 -1
- package/dist/contracts/agents.contract.d.ts +483 -1
- package/dist/contracts/agents.contract.d.ts.map +1 -1
- package/dist/contracts/agents.contract.js +20 -2
- package/dist/contracts/agents.contract.js.map +1 -1
- package/dist/contracts/approvals.contract.d.ts +99 -0
- package/dist/contracts/approvals.contract.d.ts.map +1 -0
- package/dist/contracts/approvals.contract.js +32 -0
- package/dist/contracts/approvals.contract.js.map +1 -0
- package/dist/contracts/ci.contract.d.ts +1 -4
- package/dist/contracts/ci.contract.d.ts.map +1 -1
- package/dist/contracts/ci.contract.js +1 -9
- package/dist/contracts/ci.contract.js.map +1 -1
- package/dist/contracts/claude.contract.d.ts +9 -0
- package/dist/contracts/claude.contract.d.ts.map +1 -1
- package/dist/contracts/cursor.contract.d.ts +6 -0
- package/dist/contracts/cursor.contract.d.ts.map +1 -1
- package/dist/contracts/git.contract.d.ts +63 -1
- package/dist/contracts/git.contract.d.ts.map +1 -1
- package/dist/contracts/git.contract.js +22 -4
- package/dist/contracts/git.contract.js.map +1 -1
- package/dist/contracts/grok.contract.d.ts +3 -0
- package/dist/contracts/grok.contract.d.ts.map +1 -1
- package/dist/contracts/keys.contract.d.ts +81 -0
- package/dist/contracts/keys.contract.d.ts.map +1 -0
- package/dist/contracts/keys.contract.js +51 -0
- package/dist/contracts/keys.contract.js.map +1 -0
- package/dist/contracts/panels.contract.d.ts +7 -0
- package/dist/contracts/panels.contract.d.ts.map +1 -1
- package/dist/contracts/prepush.contract.js +2 -2
- package/dist/contracts/providers.contract.d.ts +2 -0
- package/dist/contracts/providers.contract.d.ts.map +1 -1
- package/dist/contracts/runner.contract.d.ts +99 -101
- package/dist/contracts/runner.contract.d.ts.map +1 -1
- package/dist/contracts/safety.contract.d.ts +35 -0
- package/dist/contracts/safety.contract.d.ts.map +1 -0
- package/dist/contracts/safety.contract.js +32 -0
- package/dist/contracts/safety.contract.js.map +1 -0
- package/dist/contracts/sessions.contract.d.ts +211 -1
- package/dist/contracts/sessions.contract.d.ts.map +1 -1
- package/dist/contracts/settings.contract.d.ts +30 -32
- package/dist/contracts/settings.contract.d.ts.map +1 -1
- package/dist/contracts/system.contract.d.ts +277 -1
- package/dist/contracts/system.contract.d.ts.map +1 -1
- package/dist/contracts/translator.contract.d.ts +31 -3
- package/dist/contracts/translator.contract.d.ts.map +1 -1
- package/dist/contracts/usage.contract.d.ts +29 -20
- package/dist/contracts/usage.contract.d.ts.map +1 -1
- package/dist/contracts/usage.contract.js +13 -0
- package/dist/contracts/usage.contract.js.map +1 -1
- package/dist/contracts/workspace.contract.d.ts +8 -0
- package/dist/contracts/workspace.contract.d.ts.map +1 -1
- package/dist/conversation-ids.d.ts +2 -0
- package/dist/conversation-ids.d.ts.map +1 -1
- package/dist/conversation-ids.js +8 -0
- package/dist/conversation-ids.js.map +1 -1
- package/dist/credential-material.d.ts +1 -0
- package/dist/credential-material.d.ts.map +1 -1
- package/dist/credential-material.js +24 -2
- package/dist/credential-material.js.map +1 -1
- package/dist/definition.d.ts +51 -93
- package/dist/definition.d.ts.map +1 -1
- package/dist/definition.js +6 -28
- package/dist/definition.js.map +1 -1
- package/dist/events.d.ts +2947 -991
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +233 -82
- package/dist/events.js.map +1 -1
- package/dist/history-state.d.ts.map +1 -1
- package/dist/history-state.js +1 -0
- package/dist/history-state.js.map +1 -1
- package/dist/index.d.ts +2532 -1054
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -5
- package/dist/index.js.map +1 -1
- package/dist/ingress-protocol.d.ts +13 -1
- package/dist/ingress-protocol.d.ts.map +1 -1
- package/dist/ingress-protocol.js +19 -0
- package/dist/ingress-protocol.js.map +1 -1
- package/dist/mentions.d.ts +3 -0
- package/dist/mentions.d.ts.map +1 -0
- package/dist/mentions.js +13 -0
- package/dist/mentions.js.map +1 -0
- package/dist/needs-action.d.ts +7 -0
- package/dist/needs-action.d.ts.map +1 -0
- package/dist/needs-action.js +3 -0
- package/dist/needs-action.js.map +1 -0
- package/dist/overlay-lint.d.ts +7 -0
- package/dist/overlay-lint.d.ts.map +1 -0
- package/dist/overlay-lint.js +68 -0
- package/dist/overlay-lint.js.map +1 -0
- package/dist/owner-ticket.d.ts +18 -0
- package/dist/owner-ticket.d.ts.map +1 -0
- package/dist/owner-ticket.js +51 -0
- package/dist/owner-ticket.js.map +1 -0
- package/dist/plan-pools.d.ts +12 -0
- package/dist/plan-pools.d.ts.map +1 -0
- package/dist/plan-pools.js +30 -0
- package/dist/plan-pools.js.map +1 -0
- package/dist/provider-specs.d.ts +228 -0
- package/dist/provider-specs.d.ts.map +1 -0
- package/dist/provider-specs.js +124 -0
- package/dist/provider-specs.js.map +1 -0
- package/dist/quick-model.d.ts.map +1 -1
- package/dist/quick-model.js +2 -1
- package/dist/quick-model.js.map +1 -1
- package/dist/runner-protocol.js +2 -2
- package/dist/runner-protocol.js.map +1 -1
- package/dist/runtime-state.d.ts +2 -2
- package/dist/runtime-state.d.ts.map +1 -1
- package/dist/runtime-state.js +1 -1
- package/dist/runtime-state.js.map +1 -1
- package/dist/safety-policy.d.ts +49 -0
- package/dist/safety-policy.d.ts.map +1 -0
- package/dist/safety-policy.js +52 -0
- package/dist/safety-policy.js.map +1 -0
- package/dist/schemas/agent.d.ts +21 -3
- package/dist/schemas/agent.d.ts.map +1 -1
- package/dist/schemas/agent.js +18 -8
- package/dist/schemas/agent.js.map +1 -1
- package/dist/schemas/agents.d.ts +19 -0
- package/dist/schemas/agents.d.ts.map +1 -1
- package/dist/schemas/agents.js +15 -0
- package/dist/schemas/agents.js.map +1 -1
- package/dist/schemas/approvals.d.ts +241 -0
- package/dist/schemas/approvals.d.ts.map +1 -0
- package/dist/schemas/approvals.js +63 -0
- package/dist/schemas/approvals.js.map +1 -0
- package/dist/schemas/automations.d.ts +5 -0
- package/dist/schemas/automations.d.ts.map +1 -1
- package/dist/schemas/ci.d.ts +5 -9
- package/dist/schemas/ci.d.ts.map +1 -1
- package/dist/schemas/ci.js +3 -10
- package/dist/schemas/ci.js.map +1 -1
- package/dist/schemas/computers.d.ts +31 -5
- package/dist/schemas/computers.d.ts.map +1 -1
- package/dist/schemas/computers.js +7 -5
- package/dist/schemas/computers.js.map +1 -1
- package/dist/schemas/environment.d.ts +11 -131
- package/dist/schemas/environment.d.ts.map +1 -1
- package/dist/schemas/environment.js +5 -42
- package/dist/schemas/environment.js.map +1 -1
- package/dist/schemas/git-history.d.ts +4 -0
- package/dist/schemas/git-history.d.ts.map +1 -1
- package/dist/schemas/git.d.ts +179 -0
- package/dist/schemas/git.d.ts.map +1 -1
- package/dist/schemas/git.js +39 -1
- package/dist/schemas/git.js.map +1 -1
- package/dist/schemas/panels.d.ts +21 -0
- package/dist/schemas/panels.d.ts.map +1 -1
- package/dist/schemas/panels.js +5 -0
- package/dist/schemas/panels.js.map +1 -1
- package/dist/schemas/plan-limits.d.ts +50 -3
- package/dist/schemas/plan-limits.d.ts.map +1 -1
- package/dist/schemas/plan-limits.js +11 -6
- package/dist/schemas/plan-limits.js.map +1 -1
- package/dist/schemas/provider-oauth.d.ts +6 -0
- package/dist/schemas/provider-oauth.d.ts.map +1 -1
- package/dist/schemas/provider-subscriptions.d.ts +2 -1
- package/dist/schemas/provider-subscriptions.d.ts.map +1 -1
- package/dist/schemas/provider-subscriptions.js +2 -1
- package/dist/schemas/provider-subscriptions.js.map +1 -1
- package/dist/schemas/settings.d.ts +29 -16
- package/dist/schemas/settings.d.ts.map +1 -1
- package/dist/schemas/settings.js +13 -20
- package/dist/schemas/settings.js.map +1 -1
- package/dist/schemas/system.d.ts +3 -0
- package/dist/schemas/system.d.ts.map +1 -1
- package/dist/schemas/system.js +5 -1
- package/dist/schemas/system.js.map +1 -1
- package/dist/schemas/workspace-repos.d.ts +14 -0
- package/dist/schemas/workspace-repos.d.ts.map +1 -1
- package/dist/schemas/workspace-repos.js +5 -0
- package/dist/schemas/workspace-repos.js.map +1 -1
- package/dist/schemas/workspace-tree.d.ts +1 -0
- package/dist/schemas/workspace-tree.d.ts.map +1 -1
- package/dist/schemas/workspace-tree.js +3 -0
- package/dist/schemas/workspace-tree.js.map +1 -1
- package/dist/transcript-fold.d.ts +31 -0
- package/dist/transcript-fold.d.ts.map +1 -0
- package/dist/transcript-fold.js +457 -0
- package/dist/transcript-fold.js.map +1 -0
- package/dist/workspace-state.d.ts +20 -3
- package/dist/workspace-state.d.ts.map +1 -1
- package/dist/workspace-state.js +22 -2
- package/dist/workspace-state.js.map +1 -1
- package/package.json +27 -5
- package/src/agent-catalog.test.ts +1 -1
- package/src/agent-catalog.ts +76 -555
- package/src/agent-run-model.test.ts +31 -15
- package/src/agent-run-model.ts +26 -12
- package/src/agent-runtimes.ts +419 -0
- package/src/approvals-execution.ts +96 -0
- package/src/arrival.ts +160 -0
- package/src/capability-ledger.test.ts +6 -4
- package/src/card-status.ts +93 -0
- package/src/chores/chores.ts +6 -3
- package/src/command-classes.test.ts +25 -0
- package/src/command-classes.ts +47 -5
- package/src/command-run.ts +78 -0
- package/src/contract-lock.test.ts +1 -1
- package/src/contract-lock.ts +2 -2
- package/src/contracts/agents.contract.ts +35 -2
- package/src/contracts/approvals.contract.ts +37 -0
- package/src/contracts/ci.contract.ts +0 -13
- package/src/contracts/git.contract.ts +28 -3
- package/src/contracts/keys.contract.ts +79 -0
- package/src/contracts/prepush.contract.ts +3 -3
- package/src/contracts/safety.contract.ts +48 -0
- package/src/contracts/usage.contract.ts +22 -0
- package/src/conversation-ids.test.ts +31 -1
- package/src/conversation-ids.ts +37 -3
- package/src/credential-material.test.ts +69 -1
- package/src/credential-material.ts +86 -5
- package/src/definition.ts +25 -53
- package/src/events.ts +508 -198
- package/src/history-state.ts +6 -0
- package/src/index.ts +24 -5
- package/src/ingress-protocol.ts +52 -1
- package/src/mentions.test.ts +22 -0
- package/src/mentions.ts +25 -0
- package/src/needs-action.ts +14 -0
- package/src/overlay-lint.test.ts +89 -0
- package/src/overlay-lint.ts +116 -0
- package/src/owner-ticket.test.ts +54 -0
- package/src/owner-ticket.ts +102 -0
- package/src/plan-pools.test.ts +71 -0
- package/src/plan-pools.ts +82 -0
- package/src/provider-specs.test.ts +130 -0
- package/src/provider-specs.ts +352 -0
- package/src/quick-model.ts +9 -5
- package/src/runner-protocol.ts +2 -2
- package/src/runtime-state.ts +6 -6
- package/src/safety-policy.ts +165 -0
- package/src/schemas/agent.ts +62 -17
- package/src/schemas/agents.ts +71 -0
- package/src/schemas/approvals.ts +174 -0
- package/src/schemas/ci.ts +19 -26
- package/src/schemas/computers.ts +52 -11
- package/src/schemas/environment.ts +21 -100
- package/src/schemas/git.ts +121 -6
- package/src/schemas/issues.ts +1 -1
- package/src/schemas/panels.ts +20 -0
- package/src/schemas/plan-limits.ts +58 -11
- package/src/schemas/provider-subscriptions.ts +7 -2
- package/src/schemas/settings.ts +67 -93
- package/src/schemas/system.ts +12 -1
- package/src/schemas/workspace-repos.ts +9 -0
- package/src/schemas/workspace-tree.ts +11 -0
- package/src/transcript-fold.test.ts +493 -0
- package/src/transcript-fold.ts +655 -0
- package/src/workspace-state.test.ts +77 -29
- package/src/workspace-state.ts +99 -31
- package/dist/contracts/drafts.contract.d.ts +0 -57
- package/dist/contracts/drafts.contract.d.ts.map +0 -1
- package/dist/contracts/drafts.contract.js +0 -32
- package/dist/contracts/drafts.contract.js.map +0 -1
- package/dist/definition-action.d.ts +0 -7
- package/dist/definition-action.d.ts.map +0 -1
- package/dist/definition-action.js +0 -3
- package/dist/definition-action.js.map +0 -1
- package/dist/publish-drafts.d.ts +0 -7
- package/dist/publish-drafts.d.ts.map +0 -1
- package/dist/publish-drafts.js +0 -20
- package/dist/publish-drafts.js.map +0 -1
- package/dist/schemas/drafts.d.ts +0 -84
- package/dist/schemas/drafts.d.ts.map +0 -1
- package/dist/schemas/drafts.js +0 -44
- package/dist/schemas/drafts.js.map +0 -1
- package/src/contracts/drafts.contract.ts +0 -35
- package/src/definition-action.ts +0 -8
- package/src/publish-drafts.ts +0 -59
- package/src/schemas/drafts.ts +0 -108
|
@@ -53,13 +53,23 @@ const MIN_VALUE = 6;
|
|
|
53
53
|
* content of `.git-credentials`, and the shape a `DATABASE_URL` hides one in).
|
|
54
54
|
*
|
|
55
55
|
* These are checked first and independently of any key, because half of these files have no `key = value` in
|
|
56
|
-
* them at all.
|
|
57
|
-
|
|
56
|
+
* them at all.
|
|
57
|
+
*
|
|
58
|
+
* SPLIT IN TWO because the two halves are MASKED differently (maskCredentialMaterial below) though they DETECT
|
|
59
|
+
* identically: a structural shape matches a header or an authority whose surroundings must survive the mask (a
|
|
60
|
+
* PEM's body is the secret, not its `-----BEGIN` line; a URL's host is not the secret), and an issued token is
|
|
61
|
+
* the credential entire, wherever it turns up, with nothing around it to keep. */
|
|
62
|
+
const STRUCTURAL_SHAPES = [
|
|
58
63
|
/-----BEGIN (?:[A-Z0-9]+ )*PRIVATE KEY-----/,
|
|
59
64
|
/PuTTY-User-Key-File-\d/,
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
65
|
+
/* scheme://user:password@host — the password is the point; a Sentry DSN (`https://key@host`) has no colon
|
|
66
|
+
* before the `@` and is deliberately not this. A userinfo that is nothing but asterisks is a password
|
|
67
|
+
* somebody already masked (maskCredentialMaterial below leaves this exact shape behind), and reading it as
|
|
68
|
+
* a credential would have a masked file still answer "yes, there is one in here". */
|
|
69
|
+
/\b[a-z][a-z0-9+.-]*:\/\/[^\s/:@]+:(?!\*+@)[^\s/@]{3,}@/i,
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
const ISSUED_TOKENS = [
|
|
63
73
|
/\bnpm_[A-Za-z0-9]{30,}/,
|
|
64
74
|
/\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{30,}/,
|
|
65
75
|
/\bgithub_pat_[A-Za-z0-9_]{50,}/,
|
|
@@ -76,6 +86,8 @@ const TOKEN_SHAPES = [
|
|
|
76
86
|
/\bey[A-Za-z0-9_-]{10,}\.ey[A-Za-z0-9_-]{10,}\./,
|
|
77
87
|
];
|
|
78
88
|
|
|
89
|
+
const TOKEN_SHAPES = [...STRUCTURAL_SHAPES, ...ISSUED_TOKENS];
|
|
90
|
+
|
|
79
91
|
/* A VALUE DEFERRED TO SOMEWHERE ELSE, removed before anything is read, because it is not one value but two
|
|
80
92
|
* things to get wrong. `STRIPE_SECRET={{secret:STRIPE}}` holds no credential — that is the platform's own
|
|
81
93
|
* convention for a file that must not hold one — and yet it reads as a credential twice over: the outer
|
|
@@ -98,3 +110,72 @@ export const holdsCredentialMaterial = (file: string): boolean => {
|
|
|
98
110
|
}
|
|
99
111
|
return false;
|
|
100
112
|
};
|
|
113
|
+
|
|
114
|
+
/* THE SAME DEFINITION APPLIED RATHER THAN ASKED: the text back with every credential in it blanked, and
|
|
115
|
+
* everything else byte for byte.
|
|
116
|
+
*
|
|
117
|
+
* WHERE IT RUNS is what lets it be this blunt (sandbox agent/agent-redaction.ts): only over a tool result whose
|
|
118
|
+
* INPUT named credential material — a Read of `.env`, a `cat ~/.npmrc`, a Grep through `~/.aws`. The name
|
|
119
|
+
* heuristics that run over ARBITRARY output have to be timid, and the timidity is measured rather than
|
|
120
|
+
* theoretical: matching on the key alone rewrote `oauthToken === undefined` mid-comparison and broke a JSON
|
|
121
|
+
* body at `"cacheReadTokens":26170149`. This pass is pointed at a file the path table already calls a
|
|
122
|
+
* credential store, where a `key = value` IS the credential and there is no prose to protect.
|
|
123
|
+
*
|
|
124
|
+
* IT COVERS THE HALF THE VAULT CANNOT. Value masking is exact and complete for what this sandbox STORES, and
|
|
125
|
+
* blind to everything else: the project's own `.env`, a token a deploy minted an hour ago, whatever the owner
|
|
126
|
+
* pasted into the repo this agent was pointed at. Those are the credentials a read actually leaks, and with
|
|
127
|
+
* them blanked a read is worth about as much to a stranger as the file's key names — which is what lets the
|
|
128
|
+
* command gate stop asking about READS and ask about SENDING (sandbox guard/actions.ts).
|
|
129
|
+
*
|
|
130
|
+
* THE MASK IS ANONYMOUS, never a `{{secret:name}}` reference. A reference is a promise that the exits resolve
|
|
131
|
+
* it back to a value, and this pass is inferring from shape: minting one would put a token in the model's hands
|
|
132
|
+
* that resolves to nothing, discovered when the deploy 401s. The cost is stated plainly: a file the model
|
|
133
|
+
* rewrites wholesale from a masked read loses the value it was never shown. That is the same trade the terminal
|
|
134
|
+
* filter has always made, and the alternative is handing the model the credential so it can copy it back.
|
|
135
|
+
*
|
|
136
|
+
* A PuTTY `.ppk` body is the known gap: unlike PEM it has no closing line to bound the mask, so its key
|
|
137
|
+
* material survives this pass. The file still reads as credential material to everything else here, so the gate
|
|
138
|
+
* still asks before a command carrying it reaches the internet. */
|
|
139
|
+
const MASK = "***";
|
|
140
|
+
|
|
141
|
+
// The `g` twins, built once: the tables above are written without `g` because `test` is what the detector
|
|
142
|
+
// wants, and `replace`/`replaceAll` demands one.
|
|
143
|
+
const globally = (patterns: readonly RegExp[]): readonly RegExp[] => patterns.map((pattern) => new RegExp(pattern.source, `${pattern.flags}g`));
|
|
144
|
+
const ISSUED_TOKENS_G = globally(ISSUED_TOKENS);
|
|
145
|
+
const CREDENTIAL_ASSIGNMENT_G = new RegExp(CREDENTIAL_ASSIGNMENT.source, CREDENTIAL_ASSIGNMENT.flags);
|
|
146
|
+
|
|
147
|
+
/* The two structural shapes that mask to something other than themselves. A PEM's header and footer stay so the
|
|
148
|
+
* model can still see WHICH key it is looking at and that a key is what it is looking at; a URL keeps its scheme,
|
|
149
|
+
* user and host, because a `DATABASE_URL` with the host blanked is a connection string nobody can debug. */
|
|
150
|
+
const PRIVATE_KEY_BLOCK = /(-----BEGIN ((?:[A-Z0-9]+ )*)PRIVATE KEY-----)[\s\S]*?(-----END \2PRIVATE KEY-----)/g;
|
|
151
|
+
const URL_PASSWORD = /(\b[a-z][a-z0-9+.-]*:\/\/[^\s/:@]+:)(?!\*+@)[^\s/@]{3,}@/gi;
|
|
152
|
+
|
|
153
|
+
/* A VALUE THAT OPENS A DEFERRED REFERENCE, skipped whole. The detector cuts these out before it looks
|
|
154
|
+
* (DEFERRED_VALUE); masking cannot cut anything out, so it recognises the OPENER instead — and the opener is
|
|
155
|
+
* what a truncated one leaves behind. `STRIPE_SECRET={{secret:STRIPE}}` is the case that matters: the bare-value
|
|
156
|
+
* arm stops at the first `}`, so what reaches this test is `{{secret:STRIPE`, which no whole-value placeholder
|
|
157
|
+
* pattern can match and which masking would turn into `***}}` — this workspace's own convention for a file that
|
|
158
|
+
* holds no credential, silently vandalised. Anchored at the start so a generated password that merely CONTAINS
|
|
159
|
+
* a `$` is still masked. */
|
|
160
|
+
const DEFERRED_OPENER = /^(?:\{\{|\$)/;
|
|
161
|
+
|
|
162
|
+
export const maskCredentialMaterial = (text: string): string =>
|
|
163
|
+
ISSUED_TOKENS_G.reduce((masked, token) => masked.replace(token, MASK), text)
|
|
164
|
+
.replace(PRIVATE_KEY_BLOCK, `$1\n${MASK}\n$3`)
|
|
165
|
+
.replace(URL_PASSWORD, `$1${MASK}@`)
|
|
166
|
+
/* The value of a credential-named assignment, in place, with its key, separator and quoting left
|
|
167
|
+
* standing: `GITHUB_TOKEN="***"` is a line the model can still reason about and still rewrite, where a
|
|
168
|
+
* blanked-out line is a config it cannot read at all. The skips are the detector's own — a value too
|
|
169
|
+
* short to be issued, a template's placeholder, a `${VAR}` or `{{secret:NAME}}` deferred elsewhere —
|
|
170
|
+
* so the two halves agree on what a credential is and nothing is masked that was never one. */
|
|
171
|
+
.replace(CREDENTIAL_ASSIGNMENT_G, (match, ...groups: unknown[]) => {
|
|
172
|
+
const value = (groups[0] ?? groups[1] ?? groups[2] ?? "") as string;
|
|
173
|
+
const trimmed = value.trim();
|
|
174
|
+
if (trimmed.length < MIN_VALUE || PLACEHOLDER.test(trimmed) || DEFERRED_OPENER.test(trimmed)) {
|
|
175
|
+
return match;
|
|
176
|
+
}
|
|
177
|
+
// The value is the last thing the pattern matched, so its own text locates it inside the match
|
|
178
|
+
// without the pattern having to hand back offsets.
|
|
179
|
+
const at = match.lastIndexOf(value);
|
|
180
|
+
return `${match.slice(0, at)}${MASK}${match.slice(at + value.length)}`;
|
|
181
|
+
});
|
package/src/definition.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import {
|
|
2
|
+
import { NeedsActionSchema } from "./needs-action.js";
|
|
3
3
|
import { CapabilitySchema } from "./schemas/capabilities.js";
|
|
4
4
|
import { SandboxSettingsSchema } from "./schemas/settings.js";
|
|
5
5
|
|
|
@@ -34,7 +34,7 @@ export type DefinitionRepository = z.infer<typeof DefinitionRepositorySchema>;
|
|
|
34
34
|
/* THE WORKSPACE ITSELF, by reference. `/work` is a git repo of its own (the daemon's `root` scope, git dir on
|
|
35
35
|
* /history), tracking every workspace file that is not a nested repo, the reference shelf, or daemon-internal
|
|
36
36
|
* state — which by the versioned-state allowlist means the owner's AUTHORED content: notes, skills, personas,
|
|
37
|
-
* automations, workflow and loop designs,
|
|
37
|
+
* automations, workflow and loop designs, approvals, workspace extensions. None of that has a source anywhere else,
|
|
38
38
|
* so before this section a definition could only shrug at it and a bundle was the sole way to move it.
|
|
39
39
|
*
|
|
40
40
|
* With a remote it becomes referenceable like any other repo, which is the whole point: `[workspace]` plus
|
|
@@ -105,66 +105,28 @@ export const SandboxDefinitionSchema = z.strictObject({
|
|
|
105
105
|
});
|
|
106
106
|
export type SandboxDefinition = z.infer<typeof SandboxDefinitionSchema>;
|
|
107
107
|
|
|
108
|
-
// One "do this by hand" line, the
|
|
109
|
-
// detail written as an instruction to the owner. Defined in its own leaf module (
|
|
110
|
-
//
|
|
111
|
-
export {
|
|
108
|
+
// One "do this by hand" line, the honesty unit the arrival surface carries too: a subject the UI bolds and a
|
|
109
|
+
// detail written as an instruction to the owner. Defined in its own leaf module (needs-action.ts says why)
|
|
110
|
+
// and re-exported here, where every consumer of the definition surface finds it.
|
|
111
|
+
export { NeedsActionSchema, type NeedsAction } from "./needs-action.js";
|
|
112
112
|
|
|
113
113
|
// What GET /definition answers: the emitted TOML, plus what the derivation could not express (a repo with no
|
|
114
114
|
// remote), listed rather than silent, the export's own `excluded` discipline.
|
|
115
115
|
export const DefinitionExportSchema = z.object({
|
|
116
116
|
toml: z.string(),
|
|
117
|
-
omitted: z.array(
|
|
117
|
+
omitted: z.array(NeedsActionSchema),
|
|
118
118
|
});
|
|
119
119
|
export type DefinitionExport = z.infer<typeof DefinitionExportSchema>;
|
|
120
120
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
id: z.string(),
|
|
126
|
-
kind: z.enum(["workspace", "repo", "capability", "environment", "settings"]),
|
|
127
|
-
label: z.string(),
|
|
128
|
-
detail: z.string().optional(),
|
|
129
|
-
/* False when the target already holds this piece (the repo's directory exists, a capability with that id
|
|
130
|
-
* exists): a definition lands BESIDE what is there, never over it, so an inapplicable item renders greyed
|
|
131
|
-
* with its reason rather than disappearing. */
|
|
132
|
-
applicable: z.boolean(),
|
|
133
|
-
reason: z.string().optional(),
|
|
134
|
-
});
|
|
135
|
-
export type DefinitionItem = z.infer<typeof DefinitionItemSchema>;
|
|
136
|
-
|
|
137
|
-
export const DefinitionPlanSchema = z.object({
|
|
138
|
-
// Names the held definition for the apply call. Minted per plan; a new plan replaces the held one.
|
|
139
|
-
token: z.string(),
|
|
140
|
-
name: z.string().optional(),
|
|
141
|
-
items: z.array(DefinitionItemSchema),
|
|
142
|
-
// What is already known not to move mechanically (credentials to enter, an overlay to approve), surfaced
|
|
143
|
-
// at PREVIEW time so the owner ticks with open eyes, the migration surface's rule.
|
|
144
|
-
needsAction: z.array(DefinitionActionSchema),
|
|
145
|
-
});
|
|
146
|
-
export type DefinitionPlan = z.infer<typeof DefinitionPlanSchema>;
|
|
147
|
-
|
|
148
|
-
export const DefinitionApplySchema = z.object({
|
|
149
|
-
token: z.string(),
|
|
150
|
-
// The ticked item ids. Ids the re-derived plan does not contain are ignored rather than erroring.
|
|
151
|
-
items: z.array(z.string()),
|
|
152
|
-
});
|
|
153
|
-
export type DefinitionApply = z.infer<typeof DefinitionApplySchema>;
|
|
154
|
-
|
|
155
|
-
export const DefinitionReportSchema = z.object({
|
|
156
|
-
applied: z.array(z.object({ id: z.string(), label: z.string() })),
|
|
157
|
-
// Ticked and did not land, each with the reason (a clone that failed, a full disk). Distinct from
|
|
158
|
-
// inapplicable items, which were never attempted.
|
|
159
|
-
failed: z.array(z.object({ id: z.string(), label: z.string(), error: z.string() })),
|
|
160
|
-
needsAction: z.array(DefinitionActionSchema),
|
|
161
|
-
});
|
|
162
|
-
export type DefinitionReport = z.infer<typeof DefinitionReportSchema>;
|
|
121
|
+
/* APPLYING one is not here. A definition is one of four things that can ARRIVE in a sandbox, and it lands
|
|
122
|
+
* through the shared pipeline in arrival.ts (ArrivalPlan → ArrivalApply → ArrivalReport) rather than through
|
|
123
|
+
* a plan/apply/report trio of its own. What stays on this file is the outbound half and the read: deriving
|
|
124
|
+
* the document, and where this sandbox stands relative to one. */
|
|
163
125
|
|
|
164
126
|
// Where this sandbox stands relative to a definition: one line per difference, empty when they agree. The
|
|
165
127
|
// drift answer, computable because the emitter is deterministic.
|
|
166
128
|
export const DefinitionDiffSchema = z.object({
|
|
167
|
-
differences: z.array(
|
|
129
|
+
differences: z.array(NeedsActionSchema),
|
|
168
130
|
});
|
|
169
131
|
export type DefinitionDiff = z.infer<typeof DefinitionDiffSchema>;
|
|
170
132
|
|
|
@@ -213,18 +175,28 @@ export type WorkspaceRemote = z.infer<typeof WorkspaceRemoteSchema>;
|
|
|
213
175
|
* A bundle is DEFINITION + STATE: its manifest embeds the same definition `GET /definition` emits, and the
|
|
214
176
|
* tar entries behind it carry what no definition can reference (git dirs, transcripts, ledgers). One schema,
|
|
215
177
|
* two doors, which is what keeps the two formats from drifting into different answers about what an
|
|
216
|
-
* environment IS.
|
|
217
|
-
*
|
|
178
|
+
* environment IS. A manifest whose version this daemon does not know is refused rather than guessed at.
|
|
179
|
+
*
|
|
180
|
+
* Version 3 added `repos`, and it is the field that made a bundle previewable. Taking one in is now a plan
|
|
181
|
+
* the owner ticks (arrival.ts), and a plan has to say what is in the tar BEFORE the tar is read: which
|
|
182
|
+
* repositories a bundle carries could previously only be learned by walking every entry, because
|
|
183
|
+
* `definition.repositories` lists only the ones that HAVE a remote to be named by. A bundle that cannot
|
|
184
|
+
* describe its own contents can only be offered whole, which is exactly the all-or-nothing this replaced.
|
|
218
185
|
*/
|
|
219
186
|
export const BundleManifestSchema = z.object({
|
|
220
187
|
// Bumped when the layout changes in a way an older daemon would misread. Refused rather than guessed at.
|
|
221
|
-
version: z.literal(
|
|
188
|
+
version: z.literal(3),
|
|
222
189
|
// Where it came from, for the report's first line. Never used to authorize anything.
|
|
223
190
|
sandbox: z.object({ name: z.string() }).optional(),
|
|
224
191
|
createdAt: z.number(),
|
|
225
192
|
// The owner's export-time choice; the restorer re-derives every decision from the manifests rather than
|
|
226
193
|
// trusting this, and uses it only to explain what is missing.
|
|
227
194
|
secrets: z.boolean(),
|
|
195
|
+
/* Every repository whose real git dir rides in this bundle, by workspace id — INCLUDING the ones no
|
|
196
|
+
* definition can name, which is the point: a repo with no remote is invisible to `definition.repositories`
|
|
197
|
+
* and is precisely the one an owner most wants carried by bytes. "root" is not listed; the workspace repo
|
|
198
|
+
* itself is not a nested repository and travels with the workspace files. */
|
|
199
|
+
repos: z.array(z.string()),
|
|
228
200
|
// The declarable shape, exactly what a definition export emits, so the restore report reasons over the
|
|
229
201
|
// same facts either door delivers.
|
|
230
202
|
definition: SandboxDefinitionSchema,
|